In version 8.3.9, we implemented a significant number of tasks to optimize different mechanisms of the platform. We would like to tell you about one of them in this article. The task in question concerns improved performance of web services.
Reuse of sessions
Insufficient performance of web services was due to the fact that each web service call had significant "overhead expenses" related to creating and terminating a session. Besides, every time a session was created, the handler SessionParametersSettings() was executed, which could be quite "heavy" in a standard configuration.
In addition, there was a functional deficiency. Web services did not have a state. This prevented us from implementing the logic that uses saved state between web service calls.
In version 8.3.9, we fine-tuned the mechanism for web services (SOAP services, HTTP services, and OData services). As a result, their performance has improved by approximately 10 times.
We conducted tests on the standard 1C:Enterprise Accounting configuration. We have added HTTP services that select data from the Counterparties catalog. The test was that the client called the service 100 times one after the other. In the old mode, it took 29.9 sec; in the new modes - 3 sec on average.
These results were achieved due to the fact that we have implemented two different strategies to ensure reuse of sessions:
- Automatic reuse of sessions from the pool
- Managing sessions using HTTP headers
When sessions are automatically reused, the client has no control over the number of sessions and their lifetime. It is just automatically assigned a session from an existing session pool. This strategy is suitable for high-load public services that are accessed by clients, which perform pre-configured operations and which have uniform privileges.
For example, this could be automation of commercial activities of remote retail outlets that take into account periods of peak load on the server. The required number of sessions will be allocated. They will be closed as the load decreases.
Another example is getting/committing files in 1C:Document Management via HTTP services. For these operations, you can use the same dedicated user.
Manual session management strategy implies that the client independently manages the number of sessions and their lifetime. This strategy is best suited for highly integrated systems within one organization. You can implement your own algorithm, which will manage the session lifetime and their quantity.
You can set the use a certain strategy in the configuration object tree, and, if necessary, override it in the default.vrd file. In the configuration object tree, we added two new properties to Web service and HTTP service objects:
- ReuseSessions can have AutoUse, Use, and DontUse values. AutoUse value enables automatic reuse of sessions from the pool, and Use value enables session management using HTTP headers.
- You can use SessionMaxAge property to specify how many seconds the session will be idle before the platform automatically closes it.
We have added several new attributes for elements that describe SOAP services, HTTP services, and
- reuseSessions - analog of the ReuseSessions property that can have autouse, use, and dontuse values
- sessionMaxAge - analog of the SessionMaxAge property
- poolTimeout - is used for automatic session management, contains session availability timeout
- poolSize - is used for automatic session management, contains the maximum number of sessions that can be created in the pool
For example, the default.vrd file may look like this:
default.vrd file takes precedence over the configuration. When you publish the configuration, reuseSessions and sessionMaxAge attributes are populated from the corresponding configuration properties of Web service and HTTP service objects. But if necessary, you can change these values directly in the file, and then the platform will use them instead of the values from the configuration.
<?xml version="1.0" encoding="UTF-8"?> <point xmlns="http://testserver/Demo83" xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" base="/demo" ib="Srvr="tcp://Server";Ref="demo";" enable="false" allowexecutescheduledjobs="force" enableStandardOData="true"> <standardOdata enable="true" reuseSessions="use" sessionMaxAge ="20" poolTimeout="5" poolSize="10"/> <ws> <point name="OperationalData1" alias="OperData" reuseSessions="use" sessionMaxAge="20" poolTimeout="5" poolSize="10"/> </ws> <httpServices> <service name="Example" enable="true" reuseSessions ="autouse" sessionMaxAge="20" poolTimeout="5" poolSize="10"/> </httpServices> <pool size="50" maxAge="10" attempts="2"/> </point>
Automatic reuse of sessions
Sessions are stored in the pool classified by the type of service, description of service, user name/password, separator values, and safe mode capability. The pool can also have multiple sessions with identical values of the listed attributes.
When a web service is called, the platform checks if there is an idle session with a suitable combination of these attributes. If such session exists, it is selected for call processing. If such session does not exist, a new session is created and selected for processing.
The session automatically ends after the period of inactivity expires (SessionMaxAge).
If you reached the maximum number of sessions (poolSize), the call waits for the specified time (poolTimeout). If during this time, a suitable session does not become available, you will get an error with the 406 Not Acceptable status.
Settings of the automatic session pool have effect within the publication. This means that if you have multiple publications for the same infobase, each call addresses a specific publication, and the parameters of this publication have effect. Thus, if in one publication a 3-session limit is specified, and in another publication - a 5-session limit, the total number of sessions that can be created for your infobase amounts to the sum of these values - 8.
When choosing pool size, you should take into account all classifications, in which the sessions are stored in the pool. We recommend setting the pool size to be slightly greater than the number of possible options. This will allow you to avoid a situation where the pool is filled with sessions, and a call with a new combination of separators/users cannot be processed.
This strategy is not suitable for scenarios where you need to use the saved state of the session on the server. This is due to the fact there is no guarantee that the client will be connected to the same session during the next call. As specified above, the pool can also have multiple sessions with the same values for the key attributes.
Service client initiates creation and closing of a session. To create a permanent session, the client must submit the IBSession header in the HTTP request. This header must be set manually. The start directive should be the value of this header.
POST http://testserver/Demo83/ws/ws2.1cws HTTP/1.1 … Connection: Keep-Alive Content-Type: text/xml;charset="utf-8" SOAPAction: http://testserver/Demo83/ws2#Web 1: 1 IBSession: start Content-Length: 182 …
When such header is received, the infobase session starts, authentication takes place, separators are set, and the SessionParametersSettings() handler is called on the server.
If the client requested to create a session, and the server cannot do so, the 406 Not Acceptable error message is generated.
If all is well and the session was created, the platform places the directive to set IBSession cookie with the ID of the newly created session into the HTTP response.
HTTP/1.1 200 OK Date: Thu, 02 Apr 2015 06:31:11 GMT Server: Apache/2.0.65 (Win32) Content-Length: 357 Keep-Alive: timeout=15, max=100 Set-Cookie: IBSession=43CD8102-F970-4FFB-939A-C47948F49885 Connection: Keep-Alive Content-Type: text/xml;charset="utf-8" <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <m:Operation1Response xmlns:m="http://testserver/Demo83/ws2"> <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">true</m:return> </m:Operation1Response> </soap:Body> </soap:Envelope>
To connect to a previously created session, you need to specify the IBSession cookie with the session ID.
HTTP/1.1 200 OK Date: Thu, 02 Apr 2015 06:31:12 GMT Server: Apache/2.0.65 (Win32) Content-Length: 357 Keep-Alive: timeout=15, max=99 Connection: Keep-Alive Cookie: IBSession=43CD8102-F970-4FFB-939A-C47948F49885 Content-Type: text/xml;charset="utf-8" <soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> <soap:Body> <m:Operation1Response xmlns:m="http://testserver/Demo83/ws2"> <m:return xmlns:xs="http://www.w3.org/2001/XMLSchema" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">true</m:return> </m:Operation1Response> </soap:Body> </soap:Envelope>
To end the session, you need to use IBSession header of the HTTP request. It must be set in the finish directive.
POST http://testserver/Demo83/ws/ws2.1cws HTTP/1.1 … Connection: Keep-Alive Content-Type: text/xml;charset="utf-8" SOAPAction: http://testserver/Demo83/ws2#Web 1: 1 IBSession: finish Content-Length: 182
When a message with this header is received, the server processes the call and closes the session.
This strategy allows you to implement scenarios that use the session state saved on the server. This is due to the fact that you have a unique session ID. The only thing you need to remember is that a session can be closed not only based on your “orders”, but also automatically. This happens when the inactivity period for the session (SessionMaxAge) is exceeded. Therefore you, as the service client, should be ready for that session data to be possibly reset if the session was closed.
Web services in extensions
If the web service or HTTP service configuration objects are located in the
In the future, we will consider the possibility of supporting these properties in extensions.