📜 ⬆️ ⬇️

Online checks on the federal network through RabbitMQ, 1C and black magic


Last year, the IT director of one of the largest agro-industrial holdings in Russia addressed us. The approach to the business that our client has implemented has been impressive. He was one of the first to realize the idea of ​​a full-cycle enterprise - from the field to the shelf at the grocery store. Due to the availability and high quality of products, this holding has become a recognized brand that is known and chosen. At that time, the holding included more than 650 outlets and more than 20,000 employees distributed throughout the territory of the Russian Federation.


The customer needed to ensure the fastest possible delivery of checks to the center from all outlets of Russia, including food stalls in remote villages with occasional Internet and minimal computerization.


Given this specificity, the solution of the problem turned into a fascinating adventure with a tambourine, shamans and rabbit's paws in the face of RabbitMQ. How we built a federated cluster of queues and what we encountered under the cut.


About customer issues


A holding with a large number of distributed outlets, operating in the conditions of tough competition, demanded that its managers promptly take management decisions. For this, managers needed information on checks in “real time” mode.


In the current system, the delivery of the check from the cashier to the central system reached 3 days. At the same time, there was periodically recorded not bringing information about the perfect purchase (loss of check).


It was necessary to ensure receipt of information about sales "here and now" to optimize the delivery of products to retail outlets and promptly respond to changes in product and demand balances. This information must simultaneously get into the central IC of the holding on the basis of 1C and on the computer of the merchant in a particular store / outlet.


In addition, it was necessary to ensure a centralized and operational reassessment of goods over the network, and also to connect to the BI system of the holding a stream of online data from all outlets.
As a result, the criteria for project success were formed:



For the Silver Bullet team, this was a very tempting thing, because at that time we had developed our 1C adapter for RabbitMQ and the ability to launch it into battle at long distances and loads attracted geek minds. The concept of “check position in the center in 1 second” is not so new, we presented ideas for using queues in 1C back in 2013, and even tried it out on one trading network, but at that time they were very experimental crutches that included Rabbit + 1C is C #, WCF and even some C ++.


Of course, we all saw it in smart books, which were written earlier. Therefore, I will not undertake to judge when exactly the idea of ​​queues in integration projects began to take over the world.


Anyway, the theoretical part and the architectural concept proved to be effective, only a small part remained - to do everything, test, fix bugs, document and cover. : trollface:


Diving headlong


No one knows better than the business owner about his strengths and weaknesses, so all integration projects begin with an audit of client processes, understanding the starting point (AS IS). Usually, a business survey includes:



To exclude discrepancies, we use the formalization of the AS IS and TO BE business processes in the form of BPMN schemes. It is also easier to understand it yourself, and it is easier for the customer not to miss anything when we go through the process diagram with him.


From the technical features, in the course of the audit, we found that:



AS-IS Integration Scheme


AS-IS Integration Scheme


The audit also showed that the company's business processes practically do not need to be adjusted, but an infrastructure refinement is required to ensure the smooth flow of information.


In general, we were faced with the task of reliable delivery of documents between the three components of the process: a cash register, a merchandise computer and a central office. At the same time, the computer goods manager is a machine “under the table”. It can be turned on / off at the request of the merchandiser. Or even be turned off 23 hours from 24 hours. However, when leaving the twilight, the merchandiser should see the current set of prices, balances, item positions, etc.


Choosing a solution, collecting rakes and placing crutches


Event integration on the queues has long become a commonly used pattern. When you need to transfer something somewhere, with many links, in an unreliable environment, and at the same time stream data - you need events and queues. Therefore, we chose RabbitMQ, because it is easily integrated into any (so it seemed to us) environment, including the 1C platform, for which we already had an adapter made of AMQP protocol.


RMQ is a kind of data flow manager and allows for integration in the “almost real” time mode, while maintaining weak connectivity of the systems, withstanding the load, and so on and so forth ... A good server, in a word, much has been written about Habré.


One of the nice features is out-of-the-box clustering and the ability to build distributed server clusters that work together.


image


I always liked the pictures with the integration architecture in the queues. They always consist of three cubes, in the center of which is a message broker. Let this picture be in this article, so as not to violate the canon.


When constructing the scheme, the question arose - where should the queue server be located? In which states can we have a system? Found out that there are 5 regular and emergency situations in which work should not stop.


  1. All blocks are included.
  2. The center is disconnected, there is access to the merchandiser.
  3. Merchandise disconnected, there is access to the center.
  4. Both the merchandiser and the center are disconnected.
  5. 1C system is disabled.

Checks in all these situations should make their way; trading should not stop. When you restore the channel - checks must arrive to the subscriber. Let me remind you that the outlet - it can be a rural stall. There is no separate server installed on which RMQ could be installed. It turned out that the message broker should stand directly at the checkout. Servers are an unaffordable luxury, and Rabbit is quite lightweight and can work on a small POS terminal. So why not yes?


Of course, we did not make POS the only node of the RMQ cluster, but one of the nodes of the federated cluster was placed directly on the trading terminal, running Windows Embedded. It was a little easier to say than to do, but we did it in a fun and reckless way. What now and tell.


How to put RMQ Frontol terminal


I must say that Erlang and the RMQ server itself on the Windows terminal got up almost without any problems. Problems arose in the client, which must interact with the server from the cash register software.


Frontol cashier software has quite suitable documentation, from which we found out that it is possible to customize behavior using Javascript. “Yohhu!” We said and began to google the JS client for RabbitMQ. It quickly became clear that a bummer was waiting for us. The frontage is not quite javascript. Well, that is formally yes, the syntax is the same there, but the JavaScript machine itself is from the Windows Script Host, the same one that is VBScript, cscript.exe and so on. In short, he is very old, microsofto-specific, and no sane JS client of the rabbit will work on it.


However, in the WSH ecosystem, you can use COM objects, and we headed towards the RMQ client for .NET .


Current versions of this client no longer support .NET 3.5, which we had at the POS terminal, but fortunately, the client’s source code is open, and besides, there are tags on the project github, in which .NET 3.5 is still supported. Glory to Openscore! It remained to deflate the source code of the old version of the .NET client, put the Com-Visible checkbox there and upload it to the terminal.


Interaction with Frontol cashier


Cashier software has an API that can be used to interact.


function init() { frontol.addEventListener("openDocument", "beforeOpenDocument", true); frontol.addEventListener("closeDocument", "beforeCloseDocument", true); frontol.addEventListener("closeDocument", "afterCloseDocument", false); frontol.addEventListener("closeSession", "beforeCloseSession", true); frontol.addEventListener("closeSession", "afterCloseSession", false); addPolyfills(); //   ) initRmqVariables(); createRMQConnection(); } 

The capabilities of the native JS, which is on board Windows, are extremely poor. For example, there is no Array.indexOf or JSON.stringify. But the world is not without good people. We remembered a popular browser crutch called "polyfills", and happily built them into the cashier. If we throw the jokes aside, then all the magic tricks with JS were deliberately commented on meticulously so that future generations of administrators could clearly and quickly understand what was happening, where it came from and how it works.




It quickly became clear that the JS-API does not cover part of our cases, however, since Frontol incorporates Firebird DBMS, and an ODBC provider exists for it, then using the same ADODB we will be able to access Javascript directly from the cash register and get there we need the data.


 function afterCloseSession() { var connection = getDatabaseConnection(); var qSelect = new ActiveXObject("ADODB.Command"); qSelect.ActiveConnection = connection; qSelect.CommandText = "SELECT ChequeNumber " + "FROM Document " + "WHERE " + " State = 1 " + " AND(ChequeType IN(0, 1, 2)) " 

Finally, direct work with the queue server from our JS is as follows:


 function createRMQConnection() { factory = new ActiveXObject("RabbitMQ.Client.ConnectionFactory"); factory.UserName = rmqUser; factory.Password = rmqPass; factory.VirtualHost = "/"; factory.HostName = "localhost"; try { rmqConnection = factory.CreateConnection(0); } catch (e) { throw new Error("     .   !\n" + e.message); } rmqChannel = rmqConnection.CreateModel(); rmqMessageProperties = rmqChannel.CreateBasicProperties(); rmqMessageProperties.ContentType = "text/plain"; rmqMessageProperties.ContentEncoding = "string"; rmqMessageProperties.DeliveryMode = 2; } 

Overall picture of the solution


The architecture laid down the following principles:




In accordance with the architectural solution, the following data flow diagram was created:



The resulting circuit provides the ordered characteristics for speed and works stably when any of the components fall out. After the loss and restoration of communication, the accumulated data goes to the center within 5-10 seconds. In practice, the technology of loosely coupled systems has proven its effectiveness. All events take place as if in the same office, without taking into account the various types of delays associated with territorial distribution and its various degree of availability of communication channels.


Brief conclusion


I would like to separately enjoy the amazing time we live. More recently, the use of Open Source in the production was such a kind of devotion. “Does your open source software work? So how do you like this cactus? ”Today, this is an absolute maxim.


I can’t imagine a company that doesn’t have an open source product in production. Thanks to the availability of information, open source, to implement business ideas has become much easier and faster. Need to put RMQ on ancient non-standard Javascript and Windows? There is nothing easier. Is the booze solution a bit wrong? - look how it is done and add the missing. Time-to-Market when using open products is reduced by several times. And everyone knows that a quick release of a solution means a competitive advantage.


Github, Stackoverflow, open documentation and standards make it possible to run in a matter of weeks what would have required many years of expertise in various areas of computer knowledge.


And of course, I am particularly pleased that the 1C-nick community every year goes further and further out of its closed world and merges into global IT. For example, “1C: Enterprise” today is one of the official languages ​​supported by Github, and people from the 1C community “taught” it to this language. This story probably deserves a separate article, perhaps I will write it someday. In the meantime - all the best and good luck to you!


Thank you for your time!


')

Source: https://habr.com/ru/post/422151/


All Articles