{"id":1794,"date":"2011-06-30T17:08:50","date_gmt":"2011-06-30T13:08:50","guid":{"rendered":"http:\/\/blog.denivip.ru\/?p=1794"},"modified":"2013-08-05T14:11:48","modified_gmt":"2013-08-05T10:11:48","slug":"flash-media-server-load-distribution-with-access-plug-in","status":"publish","type":"post","link":"http:\/\/blog.denivip.ru\/index.php\/2011\/06\/flash-media-server-load-distribution-with-access-plug-in\/?lang=en","title":{"rendered":"Flash Media Server: load distribution with Access plug-in"},"content":{"rendered":"<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/load-balancing.jpg\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/load-balancing.jpg\" alt=\"RTMP load balancing\" title=\"RTMP load balancing\" width=\"300\" height=\"300\" class=\"aligncenter size-full wp-image-1740\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/load-balancing.jpg 300w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/load-balancing-150x150.jpg 150w\" sizes=\"(max-width: 300px) 100vw, 300px\" \/><\/a><\/center><br \/>\nIn this article, we will discuss how you can use the FMS Access plugin for load balancing among all of its FMS fmscore processes. Also, we will brief you on how to apply the Access plugin to balance VoD content load over multiple FMS servers. <!--more--><\/p>\n<p>Access plugin is another level of FMS security, which allows you to perform lightweight authorization of incoming connections before they reach the level of SSAS applications in the fmsedge process. <\/p>\n<p>The Access plugin provides the following features:<\/p>\n<ul>\n<li>Analyze the properties of a client connection<\/li>\n<li>Analyze server statistics<\/li>\n<li>Analyze server statistics<\/li>\n<li>Send requests to the external systems<\/li>\n<\/ul>\n<p>Once a client connection arrives to the fmsedge process, fmsedge passes connection control to the Access plugin (if installed). The Access plugin business logic can now decide on how to handle this connection: accept, reject or forward it to another FMS.<\/p>\n<p><strong>Distributing FMS load among its fmscore processors<\/strong><br \/>\nOne of the most fascinating features offered by the Access plugin is the ability to make a dynamic selection of fmscore process to forward a connection, right at the moment when the inbound connection arrives to fmsedge. This helps to more or less flexibly manage client connections at the FMS level, according to your system architecture and your resources. For example, this way you can guarantee the quality of service to certain groups of customers.<\/p>\n<p>The process of binding the connection to fmscore process is well defined in<a href=\"http:\/\/help.adobe.com\/en_US\/flashmediaserver\/devguide\/WS5b3ccc516d4fbf351e63e3d11a0d662434-7fed.html#WS47C96BDA-C00C-4205-BFA5-C7EDE9000D13\"> the Adobe documentation<\/a>. Here we would like to give you an example of obtaining the fmscore process ID to which to attach a connection obtained from the client connection URI. It is clear that originally this identifier should be added to the URI, for instance, within the player used to play back the content.  The player could retrieve the ID from the load balancer or calculate it based on the parameters of requested content.  We will use the example later in the paper, when discussing load balancing with SSAS applications.<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/><\/div><\/td><td><div class=\"text codecolorer\">void MyAdaptor::onAccess(IFCAccess* pAccess) {<br \/>\n&nbsp; &nbsp; .........<br \/>\n&nbsp; &nbsp; switch(pAccess-&gt;getType()) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; case IFCAccess::CONNECT: {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ get client's URI<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const char* uri = pAccess-&gt;getValue(&quot;s-uri&quot;);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const char* tmp = 0;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ marker where core id is in the URI<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const char *pName = &quot;coreId=&quot;;<br \/>\n<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(uri &amp;&amp; (tmp=strstr(uri, pName))!=0) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ get a fmscore id<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const char *coreId = tmp + strlen(pName);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ set the fmscore id<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(!pAccess-&gt;setValue(&quot;coreIdNum&quot;, coreId)) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; \/\/ log that set is failed<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; ............<br \/>\n}<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><strong>VoD content load balancing<\/strong><br \/>\nAs a good example of using the Access plugin, we will describe and present the pieces of code of the load balancing system implemented for the VoD content broadcast platform.  Please note that this is just one of the possible options, still it is quite functional and is used in video portals with large audience. However, the efficiency of the architecture certainly depends on the content type.<\/p>\n<p>Suppose we have a pool of Edge servers with the FMS server providing access to the VoD content using a standard SSAS VoD application. The Edge servers receive content from the Origin servers that have a direct access to the VoD content storage. This means that Edges should have proxying enabled, so they could keep part of the content in the local cache on the dis\u0441.<\/p>\n<p>So, our goal is to develop a more or less intelligent load balancer for a video platform, which will reduce the load on this platform.  Reducing the load assumes, for each Edge server, efficient utilization of its resources, such as cache, network interface bandwidth, CPU, etc.<\/p>\n<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/authPlugPart3.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/authPlugPart3-e1308660077574.png\" alt=\"Flash Media Server Access plugin\" title=\"Flash Media Server Access plugin\" width=\"550\" height=\"331\" class=\"aligncenter size-full wp-image-1737\" \/><\/a><br \/>\nFig. 1. Load balancing for VoD content architecture<\/center><\/p>\n<p>For this purpose, we have developed two SSAS applications and an Access plugin.  The solution architecture is shown in Fig.   1. On the Edge server, we are going to install the Access plugin to attach the inbound client requests to the proper fmscore process.  At the same location, let&#8217;s install the edge_app SSAS application, which will collect statistics related to the file cache, the number of active users, etc., by calling <a href=\"http:\/\/help.adobe.com\/en_US\/flashmediaserver\/adminapi\/WSa4cb07693d12388431df580a12a34991ebc-8000.html#WS5b3ccc516d4fbf351e63e3d11a0d3edb98-7fa9\">FMS AdminAPI<\/a>.  Another SSAS application, balancer_app, will be responsible for initial distribution of user requests to play back certain pieces of content. So, in fact, this is quite similar to our load balancer.<\/p>\n<p>So, the client must initially access the Load Balancer, passing the content name to it. In response, it will get the Edge Server ID and fmscore process ID to which the Access plugin will attach the client request.  The load balancer periodically collects statistics (file cache content , performance characteristics, etc.) from the Edge servers. Based on this statistics, it distributes the arriving client requests using the RTMP redirect method.<\/p>\n<p><strong>Edge_app  SSAS application<\/strong><br \/>\nWe need this SSAS application to periodically collect statistics from FMS and its cache. The statistics is gathered by calling the <a href=\"http:\/\/help.adobe.com\/en_US\/flashmediaserver\/adminapi\/WSa4cb07693d12388431df580a12a34991ebc-8000.html#WS5b3ccc516d4fbf351e63e3d11a0d3edb98-7fa9\">FMS AdminAPI<\/a> methods. For our purposes, we need only 2 methods: getFileCacheStats() and getServerStats(). The first method provides statistics on the file cache in RAM grouped by the fmscore processes.  The second method provides the server statistics: the number of active connections, bandwidth allocation, CPU utilization, etc.<\/p>\n<p>Also, the application configuration file can accommodate the physical server characteristics which the load balancer can factor in to distribute the queries: the number of fmscore processes, the maximum server throughput, etc.<\/p>\n<p>All these characteristics and properties are processed and cached to be used by the balancer_app SSAS application.  For example, this way you can dump statistics from the Edge server:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/>12<br \/>13<br \/>14<br \/>15<br \/>16<br \/>17<br \/>18<br \/>19<br \/>20<br \/>21<br \/>22<br \/>23<br \/>24<br \/>25<br \/>26<br \/>27<br \/><\/div><\/td><td><div class=\"text codecolorer\">\u2029'srvStats' =&gt; { <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'appURI' =&gt; 'rtmp:\/\/192.168.1.10\/vod', <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'maxOutBandwidth' =&gt; 6250000, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'cpuUsage' =&gt; 0, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'memoryUsage' =&gt; 24, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'phisicalMem' =&gt; 35889152, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'bwIn' =&gt; 0, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'bwOut' =&gt; 0, <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'connected' =&gt; 0 <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}, <br \/>\n'cacheStats' =&gt; { <br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'cache' =&gt; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; 'cache' =&gt; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'sample_1.flv' =&gt; [<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;{<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'coreId' =&gt; 2,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'useCount' =&gt; 25<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ]<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;},<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; 'cores' =&gt; {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '0' =&gt; 0,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '1' =&gt; 0,<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; '2' =&gt; 1<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} <br \/>\n}<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><strong>Balancer_app SSAS application<\/strong><br \/>\nThis application consolidates statistics from all Edge servers by polling edge_app SSAS applications. Also, it functions as the primary entry point for all client requests for content playback, i.e., based on the collected statistics it looks for a proper Edge server among the available servers.<\/p>\n<p>For instance, you can enable load balancing based on just two criteria:<\/p>\n<ul>\n<li>whether the content is in the file cache<\/li>\n<li>the number of active clients<\/li>\n<\/ul>\n<p>The proper Edge server is found as follows. If the needed content is present in the file cache, the least loaded fmscore process is found among all Edges where the content is present. Alternatively, if there is no content in the cache, then simply the least loaded Edge server and fmscore process are found.<\/p>\n<p>After the Edge server and fmscore process are found, the application must perform RTMP redirect returning a response to the client application containing Edge server address and the ID of its fmscore process.  It would look like this:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/><\/div><\/td><td><div class=\"text codecolorer\">application.onConnect = function(client, contentName) {<br \/>\n.......<br \/>\n\/\/ find an edge server<br \/>\nvar edge = this.findEdge(contentName);<br \/>\n\/\/ find core process id at it<br \/>\nvar coreId = this.findCoreId(edge);<br \/>\nvar errObj = {errorMsg: &quot;Rejected due to redirection!&quot;, coreId: coreId};<br \/>\napplication.redirectConnection(client, edge.srv.appURI, &quot;Redirected!&quot;, errObj);<br \/>\n...........<br \/>\n}<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><strong>Access plugin<\/strong><br \/>\nThe Access plugin must be installed on the Edge server to enable correct attachment of inbound connections based on an ID passed by the load balancer (SSAS balancer_app) to fmscore process. For additional information, please refer to the beginning of this Part or to the <a href=\"http:\/\/help.adobe.com\/en_US\/flashmediaserver\/devguide\/WS5b3ccc516d4fbf351e63e3d11a0d662434-7fed.html\">Adobe Website<\/a>.<\/p>\n<p><strong>\u0421lient application (player)<\/strong><br \/>\nThe client application (a player or an air application) should be able to interact with the load balancer (SSAS balancer_app), i.e. to make a request, interpret the response with RTMP redirect and properly construct the URI with the fmscore process ID.  See Fig. 2.<\/p>\n<p><center><a href=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/fms_load_balancing.png\"><img loading=\"lazy\" decoding=\"async\" src=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/fms_load_balancing.png\" alt=\"FMS Load Balancing\" title=\"FMS Load Balancing\" width=\"523\" height=\"266\" class=\"aligncenter size-full wp-image-1738\" srcset=\"http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/fms_load_balancing.png 523w, http:\/\/blog.denivip.ru\/wp-content\/uploads\/2011\/06\/fms_load_balancing-300x152.png 300w\" sizes=\"(max-width: 523px) 100vw, 523px\" \/><\/a><br \/>\nFig. 2. Interaction of the client application and the load balancer<\/center><\/p>\n<p>First, the client application establishes a connection to the load balancer and provides to it the name of the content that the customer wants to play back:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/><\/div><\/td><td><div class=\"text codecolorer\">var nc = new NetConnection();<br \/>\nnc.connect(balancer_app_uri, &quot;sample_1.flv&quot;);<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>\u2029<br \/>\nIn response, the load balancer  finds a suitable Edge server and fmscore process, and makes RTMP redirect (the command is sent to the user), specifying in the redirect parameters the Edge server URI and fmscore process ID. A client application, for example, can handle the response as follows:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/>6<br \/>7<br \/>8<br \/>9<br \/>10<br \/>11<br \/><\/div><\/td><td><div class=\"text codecolorer\">public function onNCStatus(event:NetStatusEvent) : void {<br \/>\n&nbsp; &nbsp; ...........<br \/>\n&nbsp; &nbsp; if(event.info.code==&quot;NetConnection.Connect.Rejected) {<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; var info:Object = event.info;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; var app:Object = info.application;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; if(info.ex &amp;&amp; info.ex.code==302) { &nbsp; &nbsp;<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var coreId = app.coreId);<br \/>\n&nbsp; &nbsp; &nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; }<br \/>\n&nbsp; &nbsp; .............<br \/>\n}<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p>Finally, the client application must connect to the Edge server, passing the URI with the received identifier of the fmscore process to the Edge server, to be processed by the Access plugin:<\/p>\n<div class=\"codecolorer-container text default\" style=\"overflow:auto;white-space:nowrap;width:540px;\"><table cellspacing=\"0\" cellpadding=\"0\"><tbody><tr><td class=\"line-numbers\"><div>1<br \/>2<br \/>3<br \/>4<br \/>5<br \/><\/div><\/td><td><div class=\"text codecolorer\">\u2029......<br \/>\nvar nc = new NetConnection();<br \/>\nvar edgeURI = info.ex.redirect+&quot;?coreId=&quot;+app.coreId;<br \/>\nnc.connect(edgeURI);<br \/>\n......<\/div><\/td><\/tr><\/tbody><\/table><\/div>\n<p><strong>Summary<\/strong><br \/>\nThis is but one of the options to enable load balancing on a video platform, still it is quite flexible to approach the issue correctly. For instance, in order to extend this example to live content balancing, it is sufficient to accumulate slightly different statistics on the Edge servers and ignore the file cache. Moreover, for DVR content, the solution would not require any change at all.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>In this article, we will discuss how you can use the FMS Access plugin for load balancing among all of its FMS fmscore processes. Also, we will brief you on how to apply the Access plugin to balance VoD content load over multiple FMS servers.<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[20],"tags":[367,85,368,359,354],"_links":{"self":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/1794"}],"collection":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/comments?post=1794"}],"version-history":[{"count":4,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/1794\/revisions"}],"predecessor-version":[{"id":4864,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/posts\/1794\/revisions\/4864"}],"wp:attachment":[{"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/media?parent=1794"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/categories?post=1794"},{"taxonomy":"post_tag","embeddable":true,"href":"http:\/\/blog.denivip.ru\/index.php\/wp-json\/wp\/v2\/tags?post=1794"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}