主要内容

管理应用程序归档中的持久数据

这个示例展示了如何管理部署到的应用程序存档中的持久数据MATLAB®生产服务器™.它使用MATLAB生产服务器用于MATLAB功能执行的RESTFUR API和JSON连接MATLAB应用程序的一个或多个实例到部署在服务器上的归档文件。

MATLAB生产服务器工人无国籍。持久性提供了一种通过将多个呼叫之间的数据缓存到部署在服务器上的MATLAB代码之间的数据来维护状态。多个工人可以访问缓存数据。

该示例描述了两个工作流程。

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

  2. 使用活动的部署工作流MATLAB生产服务器实例来部署归档文件。

为了演示如何使用持久性,此示例使用旅行推销员问题,涉及在城市之间找到最短的路线。此实现存储了持久的MATLAB(MATLAB)对象。城市构成了图的节点,城市之间的距离构成了与图边相关的权值。在本例中,图是一个完整的图。测试工作流使用本地版本的路由查找函数。部署工作流使用打包到归档文件并部署到服务器的路由查找函数。MATLAB应用程序调用寻路函数。这些函数从缓存中读取和写入图形数据。

该示例的代码位于$ mps_install./客户端/ matlab / /持久性/ TravelingSalesman例子,在那里$ mps_install.是MATLAB生产服务器安装的位置。

托管使用的部署存档生产服务器编译器应用程序,您必须有一个版本MATLAB运行时它与用于创建归档文件的MATLAB版本兼容。有关更多信息,请参阅万博1manbetx支持MATLAB运行时版本

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

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

    写一个功能以检查数据缓存中是否存在城市和距离的图形。如果图表不存在,请从Excel创建它®包含距离数据并将其写入缓存的电子表格。因为只有一个MATLAB生产服务器Worker每次都可以执行此写操作,使用同步锁确保数据初始化只发生一次。

    连接到存储距离数据的缓存,如果它不存在则创建它mps.cache.connect.使用mps.sync.mutex.在写操作的持续时间内。一旦数据写入缓存,就释放锁定。

    属性初始化距离数据loadDistanceData函数。

    功能c = mps.cache.connect(cacheName,“连接”, connectionName);试= 0;尽管iskey(c,“距离”) == false && tries < 6 lk = mps.sync.mutex(“DistanceData”“连接”, connectionName);如果获得(路、10)如果iskey(c,“距离”) == false g = initDistanceData(“Distances.xlsx”);c.Distances = g;结束释放(路);结束try = try + 1;结束tf = isKey (c,“距离”);结束
  2. 写函数用于读取持久数据

    写一个函数以从数据缓存读取距离数据图。由于从缓存中读取数据是一个幂等操作,所以您无需使用同步锁。使用使用mps.cache.connect然后检索图形。

    从缓存中读取图表并使用该图表将其转换为单元格数组listDestinations函数。

    方法计算最短的可能路径findRoute函数。使用最近邻算法,从一个给定的城市开始,反复访问下一个最近的城市,直到所有的城市都被访问过。

    功能destinations = listdestinations()c = mps.cache.Connect('travelingsalesman'“连接”'便笺');如果loadDistanceData ('便笺''travelingsalesman') ==错误错误('加载距离数据失败。不能继续。);结束g = c.Distances;目的地= table2array (g.Nodes);结束
    功能[route,distance] = findRoute(start,destinations) c = mps.cache.connect('travelingsalesman'“连接”'便笺');如果loadDistanceData ('便笺''travelingsalesman') ==错误错误('加载距离数据失败。不能继续。);结束g = c.Distances;路线= {start};距离= 0;当前=开始;尽管~isempty(destinations) minDistance = Inf;nextSegment = {};n = 1:numel(目的地)[p,d] = shortestpath(g,current,destinations {n});如果d < minDistance nextSegment = p(2:end);minDistance = d;结束结束结束当前= nextSegment {};distance =距离+ minDistance;目的地= setdiff(目的地,电流);route =[路由nextSegment];结束结束
  3. 编写函数来修改持久数据

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

    使用使用的城市addDestination函数。添加城市添加新图表节点的名字以及将该节点连接到图中所有现有节点的新边。新添加边的权值由向量给出距离目的地是字符向量的单元格数组,其中包含图中其他城市的名称。

    功能count = addDestination(name, destinations, distance) count = 0; / /指定目的地c = mps.cache.connect ('travelingsalesman'“连接”'便笺');如果loadDistanceData ('便笺''travelingsalesman') ==错误错误('加载距离数据失败。不能继续。);结束路= mps.sync.mutex (“DistanceData”“连接”'便笺');如果acquire(lk,10) g = c;newDestinations = setdiff (g.Nodes。名字,目的地);如果~ isempty (newDestinations)错误(“议员:例子:TSP: MissingDestinations”......“为丢失的目的地添加距离:%s”......strjoin(newdestinations,”、“));结束src = repmat ({name} 1元素个数(目的地));G = adddge (G, src,目的地,距离);c.Distances = g;释放(路);数= numnodes (g);结束结束

  4. 写一个Matlab应用程序来调用路由查找功能

    编写一个MATLAB应用程序,将步骤2和步骤3中描述的函数封装在各自的代理函数中。这个应用程序允许你指定一个主机和端口。为了进行测试,当主机为空且端口值为0时,调用本地版本的路由查找函数。对于部署工作流,调用运行在指定主机和端口上的服务器上部署的函数。使用webwrite(MATLAB)函数向服务器发送HTTP POST请求。

    有关如何编写应用程序的更多信息,请参见使用App Designer创建和运行简单的应用程序(MATLAB)

    编写代理函数findrouteproxy.addDestinationProxy, 和listdeStinationProxy.findRouteaddDestination, 和listDestination函数,分别。

    功能目的地= listDestinationsProxy(应用)如果isempty(app.hosteditfield.value)&&......app.PortEditField.Value <= 0 destinations = 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 = destinations_RESPONSE{1};结束结束结束
    功能[路线,距离] = findRouteproxy(应用程序,开始,目的地)如果isempty(app.hosteditfield.value)&&......app.PortEditField.Value <= 0 [route,distance] = findRoute(start,destinations);返回结束findRoute_OPTIONS = weboptions (“MediaType”“application / json”“超时”现年60岁的“ContentType”“生”);findRoute_host = app.hosteditfield.Value;findroute_port = app.porteditfield.Value;start_destinations_data = {};如果nargin > 0, start_destinations_DATA = [start_destinations_DATA {start}];结束如果nargin > 1, start_destinations_DATA = [start_destinations_DATA {destination}]; / /指定目的地结束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 = Route_Distance_Response {1};结束如果nargout > 1,距离= route_distance_RESPONSE{2};结束结束结束
    功能count = adddestinationproxy(应用,姓名,目的地,距离)如果isempty(app.hosteditfield.value)&&......app.PortEditField.Value <= 0 count = addDestination(name, destinations,distance);返回结束addDestination_OPTIONS = weboptions (“MediaType”“application / json”“超时”现年60岁的“ContentType”“生”);adddestination_host = app.hosteditfield.value;adddestination_port = app.porteditfield.Value;name_destinations_distans_data = {};如果nargin > 0, name_destinations_distances_DATA = [name_destinations_distances_DATA {name}];结束如果nargin > 1, name_destinations_distances_DATA = [name_destinations_distances_DATA{目的地}];结束如果nargin > 2, name_destinations_distances_DATA = [name_destinations_distances_DATA {distance}];结束count_JSON =......webwrite (sprintf ('http://%s:%d / travelingsalesman / addestination',adddestination_host,adddestination_port),mps.json.encodeRequest(name_destinations_distans_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 = count;结束结束结束

步骤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对象用于使用Redis™持久性提供商的本地持久性服务。

    >> CTRL = mps.cache.control('便笺''redis'“端口”, 8675);

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

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

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

    > > TravelingSalesman

    应用程序以默认值for开始主持人港口

    点击装载城市加载城市列表。使用开始菜单来设置开始位置和>><<按钮选择和取消选择城市进行访问。点击计算路径显示访问所有城市的路由。

  4. 关闭应用程序时,使用持久性服务停止.停止持久服务将删除该服务存储的数据。

    > >停止(ctrl);

第3步:在部署工作流程中运行示例

要在部署工作流中运行示例,复制位于$ 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从示例目录到服务器实例的配置目录。如果你已经有了mps_cache_config文件在CONFIG目录中,编辑它以添加便条簿如示例中指定的连接mps_cache_config

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

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

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

      • matlab命令提示符:输入productionServerCompiler

    2. 在里面申请类型菜单中,选择可部署档案

    3. 在里面导出功能字段,添加findRoute.m.listDestinations.maddestination.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

    应用程序以空值for开始主持人港口.请参见服务器配置文件main_config位于server_name/ config.获取您的主机和端口价值MATLAB生产服务器实例。对于本例,可以在下面找到配置文件/ tmp / server_1 /配置.在应用程序中输入主机和端口值。

    点击装载城市加载城市列表。使用开始菜单来设置开始位置和>><<按钮选择和取消选择城市进行访问。点击计算路径显示访问所有城市的路由。

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

另请参阅

||||||

相关话题