主要内容

示例:使用持久性计算城市之间的最短路线

这个例子展示了如何管理应用程序存档部署到持久数据MATLAB®生产服务器™。它使用MATLAB生产服务器RESTful API和JSON连接一个或多个实例的MATLAB应用程序存档部署在服务器上。

MATLAB生产服务器工人是无状态的。持久性提供了一种机制来维护状态缓存数据之间的多个调用MATLAB代码部署在服务器上。多个工人对缓存数据的访问。

这个例子描述了两个工作流。

  1. 在测试应用程序的功能测试工作流在MATLAB桌面环境将它部署到服务器。

  2. 使用积极部署工作流MATLAB生产服务器实例部署归档文件。

为了演示如何使用持久性,下面的例子使用了旅行商问题,包括城市之间寻找最短的路线。这个实现存储持久MATLAB(MATLAB)对象的数据缓存。城市形式的节点图和城市之间的距离权重与图相关的边缘。在这个例子中,图形是一个完整的图像。测试工作流使用本地版本的路线寻找功能。部署工作流使用route-finding-functions打包成一个归档文件和部署到服务器。MATLAB应用程序调用路线寻找功能。这些函数读取和编写图形数据缓存。

位于的代码示例MPS_INSTALL美元/客户端/ matlab / /持久性/ TravelingSalesman例子,在那里MPS_INSTALL美元MATLAB生产服务器安装的位置。

举办一个可部署归档文件的创建生产服务器编译器应用程序,你必须有一个版本的MATLAB运行时安装与MATLAB的版本兼容的你用来创建存档。有关更多信息,请参见金宝appMATLAB运行时版本支持

步骤1:写MATLAB使用持久性函数的代码

  1. 编写一个函数来初始化持久数据

    编写一个函数来检查是否存在一个城市,距离图的数据缓存。如果图中不存在,创建一个Excel®电子表格,其中包含数据和写缓存的距离。因为只有一个MATLAB生产服务器一次工人可以执行写操作,使用同步锁来确保数据初始化只会发生一次。

    连接到缓存中存储的距离数据或如果它并不存在使用创建它mps.cache.connect。获得一个锁互斥锁使用mps.sync.mutex写操作的持续时间。释放锁一旦数据写入缓存。

    初始化数据使用的距离loadDistanceData函数。

    函数tf = loadDistanceData (connectionName cacheName) c = mps.cache.connect (cacheName,“连接”,connectionName);试= 0;isKey (c,“距离”)= = false & & < 6路= mps.sync.mutex(尝试“DistanceData”,“连接”,connectionName);如果获得(路、10)如果isKey (c,“距离”)= = false g = initDistanceData (“Distances.xlsx”);c。距离= g;结束释放(路);结束试=努力+ 1;结束tf = isKey (c,“距离”);结束
  2. 编写函数来读取持久数据

    编写一个函数来从数据缓存读取数据图的距离。因为从缓存中读取数据是一个幂等操作,您不需要使用同步锁。连接到缓存使用mps.cache.connect然后检索图。

    从缓存中读取图像并将其转换为一个细胞阵列使用listDestinations函数。

    计算使用最短的路线findRoute函数。使用最近邻算法,从一个给定的城市和多次访问下一个最近的城市,直到所有的城市参观。

    函数目的地= listDestinations () c = mps.cache.connect (“TravelingSalesman”,“连接”,“剪贴板”);如果loadDistanceData (“剪贴板”,“TravelingSalesman”)= = false错误(未能加载距离数据。不能继续。);结束g = c.Distances;目的地= table2array (g.Nodes);结束
    函数(路线、距离)= findRoute(开始,目的地)c = mps.cache.connect (“TravelingSalesman”,“连接”,“剪贴板”);如果loadDistanceData (“剪贴板”,“TravelingSalesman”)= = false错误(未能加载距离数据。不能继续。);结束g = c.Distances;路线={开始};距离= 0;当前=开始;~ isempty(目的地)minDistance =正;nextSegment = {};n = 1:元素个数(目的地)[p、d] = shortestpath (g,当前,目的地{n});如果d < minDistance nextSegment = p(2:结束);minDistance = d;结束结束结束当前= nextSegment {};距离=距离+ minDistance;目的地= setdiff(目的地,电流);路线=[路线nextSegment];结束结束
  3. 编写一个函数来修改持久数据

    编写一个函数来添加一个新的城市。添加一个城市修改图存储在数据缓存。因为这个操作需要写入缓存,使用mps.sync.mutex步骤1中描述的功能锁定。添加一个城市之后,检查图仍然完整确认每一对城市之间的距离是已知的。

    添加一个城市使用addDestination函数。添加一个城市图添加一个新节点的名字随着新的边缘连接该节点中的所有现有的节点图。新添加的边的权重向量距离目的地是一个单元阵列的特征向量图中其他城市的名字。

    函数数= addDestination(名称、目的地的距离)数= 0;c = mps.cache.connect (“TravelingSalesman”,“连接”,“剪贴板”);如果loadDistanceData (“剪贴板”,“TravelingSalesman”)= = false错误(未能加载距离数据。不能继续。);结束路= mps.sync.mutex (“DistanceData”,“连接”,“剪贴板”);如果获得(路、10)g = c.Distances;newDestinations = setdiff (g.Nodes。名字,目的地);如果~ isempty (newDestinations)错误(“议员:例子:TSP: MissingDestinations”,“添加对失踪的距离目的地:% s”,strjoin (newDestinations”、“));结束src = repmat ({name} 1元素个数(目的地));g = addedge (g, src,目的地,距离);c。距离= g;释放(路);数= numnodes (g);结束结束

  4. 写一个MATLAB应用程序调用路线寻找函数

    写一个MATLAB应用程序包装步骤2和3中描述的功能在各自的代理功能。这个应用程序允许您指定主机和端口。用于测试,调用本地版本的路线寻找函数当主机是空白和端口值0。部署工作流程,调用服务器上的部署功能运行在指定的主机和端口。使用webwrite(MATLAB)函数将HTTP POST请求发送到服务器。

    如何编写一个应用程序的更多信息,参见使用应用程序创建并运行一个简单的应用程序设计师(MATLAB)

    写代理功能findRouteProxy,addDestinationProxy,listDestinationProxyfindRoute,addDestination,listDestination函数,分别。

    函数目的地= listDestinationsProxy(应用)如果isempty (app.HostEditField.Value) & &app.PortEditField。值< = 0 = listDestinations目的地();返回;结束listDestinations_OPTIONS = weboptions (“MediaType”,“application / json”,“超时”现年60岁的“ContentType”,“生”);listDestinations_HOST = app.HostEditField.Value;listDestinations_PORT = app.PortEditField.Value;noInputJSON =”{rhs”: [],“nargout”: 1}”;destinations_JSON =webwrite (sprintf (“http://%s: % d / TravelingSalesman / listDestinations”、listDestinations_HOST listDestinations_PORT)、noInputJSON listDestinations_OPTIONS);如果iscolumn (destinations_JSON) destinations_JSON = destinations_JSON ';结束destinations_RESPONSE = mps.json.decoderesponse (destinations_JSON);如果isstruct (destinations_RESPONSE)错误(destinations_RESPONSE.id destinations_RESPONSE.message);其他的如果nargout > 0,目的地= destinations_RESPONSE {1};结束结束结束
    函数(路线、距离)= findRouteProxy(应用程序,首先,目的地)如果isempty (app.HostEditField.Value) & &app.PortEditField。值< = 0(路线、距离)= findRoute(开始,目的地);返回;结束findRoute_OPTIONS = weboptions (“MediaType”,“application / json”,“超时”现年60岁的“ContentType”,“生”);findRoute_HOST = app.HostEditField.Value;findRoute_PORT = app.PortEditField.Value;start_destinations_DATA = {};如果输入参数个数> 0,start_destinations_DATA = [start_destinations_DATA{开始});结束如果输入参数个数> 1,start_destinations_DATA = [start_destinations_DATA{目的地});结束route_distance_JSON =webwrite (sprintf (“http://%s: % d / TravelingSalesman / findRoute”、findRoute_HOST findRoute_PORT), mps.json.encoderequest (start_destinations_DATA“nargout”nargout) findRoute_OPTIONS);如果iscolumn (route_distance_JSON) route_distance_JSON = route_distance_JSON ';结束route_distance_RESPONSE = mps.json.decoderesponse (route_distance_JSON);如果isstruct (route_distance_RESPONSE)错误(route_distance_RESPONSE.id route_distance_RESPONSE.message);其他的如果nargout > 0,路线= route_distance_RESPONSE {1};结束如果nargout > 1,距离= route_distance_RESPONSE {2};结束结束结束
    函数数= addDestinationProxy(应用程序、名称、目的地,距离)如果isempty (app.HostEditField.Value) & &app.PortEditField。值< = 0数= addDestination(名称、目的地的距离);返回;结束addDestination_OPTIONS = weboptions (“MediaType”,“application / json”,“超时”现年60岁的“ContentType”,“生”);addDestination_HOST = app.HostEditField.Value;addDestination_PORT = app.PortEditField.Value;name_destinations_distances_DATA = {};如果输入参数个数> 0,name_destinations_distances_DATA = [name_destinations_distances_DATA{名称});结束如果输入参数个数> 1,name_destinations_distances_DATA = [name_destinations_distances_DATA{目的地});结束如果输入参数个数> 2,name_destinations_distances_DATA = [name_destinations_distances_DATA{距离});结束count_JSON =webwrite (sprintf (“http://%s: % d / TravelingSalesman / addDestination”、addDestination_HOST addDestination_PORT), mps.json.encoderequest (name_destinations_distances_DATA“nargout”nargout) addDestination_OPTIONS);如果iscolumn (count_JSON) count_JSON = count_JSON ';结束count_RESPONSE = mps.json.decoderesponse (count_JSON);如果isstruct (count_RESPONSE)错误(count_RESPONSE.id count_RESPONSE.message);其他的如果nargout > 0,数= count_RESPONSE {1};结束结束结束

步骤2:运行示例测试工作流

在MATLAB桌面环境中测试示例代码。为此,复制所有文件位于MPS_INSTALL美元/客户端/ matlab / /持久性/ TravelingSalesman例子一个可写的文件夹在您的系统,例如,/ tmp / persistence_example。启动MATLAB桌面和设置当前工作目录/ tmp / persistence_example使用cd(MATLAB)命令。

出于测试目的,控制持久性服务从MATLAB桌面mps.cache.control函数。这个函数返回一个mps.cache.Controller对象管理本地持久化服务的生命周期。

  1. 创建一个mps.cache.Controller对象为当地持久性服务使用复述,™持久性提供者。

    > > ctrl = mps.cache.control (“剪贴板”,“复述”,“端口”,8675);

    当活跃,该控制器可以连接命名便条簿。连接名称链接缓存存储位置在持久性服务。的mps.cache.connect功能需要连接名称创建数据缓存。的MATLAB生产服务器管理员设置缓存配置文件中的连接名称mps_cache_config。通过使用相同的名称在MATLAB桌面会话连接,您使您的代码将从开发到测试到生产没有变化。

  2. 启动持久性服务使用开始

    > >开始(ctrl);
  3. 启动TravelingSalesman路线寻找应用程序使用持久性服务。

    > > TravelingSalesman

    应用程序开始的默认值主机港口

    点击负载的城市加载的城市列表。使用开始菜单设置起始位置和> >< <按钮来选择和取消选择城市参观。点击计算路径显示一个路线,访问所有的城市。

  4. 当你关闭应用程序时,停止使用的持久性服务停止。停止一个持久化服务将删除所存储的数据服务。

    > >停止(ctrl);

第三步:运行示例部署工作流

要运行示例在部署工作流,复制所有文件位于MPS_INSTALL美元/客户端/ matlab / /持久性/ TravelingSalesman例子一个可写文件夹在您的系统上,例如,/ tmp / persistence_example。启动MATLAB桌面和设置当前工作目录/ tmp / persistence_example使用MATLABcd(MATLAB)命令。

部署工作流管理持久性服务的生命周期之外的MATLAB桌面环境,并调用路线寻找功能打包成一个存档部署到服务器上。

  1. 创建一个MATLAB生产服务器实例

    从命令行创建一个服务器系统使用mps-new。有关更多信息,请参见创建服务器实例。如果您还没有设置您的服务器环境中,明白了mps-setup为更多的信息。

    创建一个新的服务器server_1位于文件夹tmp

    mps-new / tmp / server_1

    另外,使用MATLAB生产服务器仪表板来创建一个服务器。有关更多信息,请参见设置和登录到MATLAB仪表盘生产服务器

  2. 创建一个持久性服务连接

    部署归档文件需要持久性服务连接命名便条簿。使用仪表板来创建便条簿连接或复制该文件mps_cache_config从示例目录的config目录服务器实例。如果你已经有了一个mps_cache_config在你的配置文件目录,添加编辑它便条簿连接指定的例子mps_cache_config

  3. 创建一个可部署归档文件与生产服务器编译器应用程序并将其部署到服务器

    1. 开放生产服务器编译器应用程序

      • MATLAB将来发布:应用程序选项卡,在应用程序部署,点击生产服务器编译器

      • MATLAB命令提示:输入productionServerCompiler

    2. 应用程序类型菜单中,选择可部署的存档

    3. 导出功能字段,添加findRoute.m,listDestinations.maddDestination.m

    4. 档案信息、重命名存档TravelingSalesman

    5. 你所需的额外文件存档,添加Distances.xlsx

    6. 点击

    7. 生成的可部署归档文件TravelingSalesman.ctf位于for_redistribution项目的文件夹。复制TravelingSalesman.ctf文件到auto_deploy服务器的文件夹,/ tmp / server_1 / auto_deploy在本例中,主机。

  4. 启动服务器实例

    从系统启动服务器命令行中使用mps-start

    mps-start - c / tmp / server_1
    另外,使用仪表板启动服务器。

  5. 启动持久性服务

    从命令行启动持久性服务系统使用mps-cache

    mps-cache开始- c/ tmp / server_1——连接便条簿
    另外,使用仪表板和附加持久性服务开始。

  6. 测试应用程序

    启动TravelingSalesman路线寻找应用程序使用持久性服务。

    > > TravelingSalesman

    应用程序开始空值主机港口。指的是服务器配置文件main_config位于server_name/配置你的主机和端口值MATLAB生产服务器实例。对于这个示例,找到配置文件/ tmp / server_1 /配置。在应用程序输入的主机和端口值。

    点击负载的城市加载的城市列表。使用开始菜单设置起始位置和> >< <按钮来选择和取消选择城市参观。点击计算路径显示一个路线,访问所有的城市。

结果从测试环境工作流和工作流部署环境是相同的。

另请参阅

||||||

相关的话题