Cloud-based blogs collect Skynet features for future validation in code one by one.
“ ... "Some excerpts from the cloud-wind BLOG.
1. C implementation based on the Erlang-actor mode
"A code-compliant C module, starting from a dynamic library (so file), binds a digital ID that never repeats (even if the module exits) as its handle. The module is called a service, and the service room is free to send messages. Each module can register a callback function with the Skynet framework to receive messages sent to it. Each service is driven by a single message packet, and when no packets arrive, they are suspended, consuming 0 of CPU resources. If autonomous logic is required, it can be triggered periodically using the timeout message provided by the Skynet system. ”
"Skynet in principle argues that all services are done collaboratively in the same OS process. Skynet is only responsible for sending a packet from within a service, allowing another service within the same process to receive it, and call the corresponding callback function to handle it. It guarantees that the initialization process of the module, each independent callback call, is mutually thread-safe. ”
2. Skynet unresolved issues
"Skynet message delivery is one-way, delivered in packets. The concept of a TCP connection is not defined. There is also no agreement to contract RPC calls. Does not specify the encoding of the packet, and does not provide a consistent complex data structure for the column set API. ”
3. Optimization of inter-service communication
If necessary, the packet can implement 0 copies during processing: "Skynet does not care how packets are packaged." It simply passes the pointer to the packet, and the length of the packet you claim (not necessarily the actual length). Since the service is within the same process, the receiver obtains the pointer and can process the data it refers to directly. ”
Of course, the vast majority of scenarios should be based on a different approach: "Skynet recommends a more reliable, slightly lower performance scenario: it contracts that each service sends out packets that are copied to contiguous memory allocated with malloc." When the receiver finishes processing the data block (after the callback function call is processed), the free function is called by default to release the occupied memory. "So that at least the direct access to memory, not the way messages are communicated.
Inter-Service Communication session: the distinction between service callbacks in different services; type: message types;
4. Inter-process communication:
"The number of services within a single Skynet process is limited by the number of handle. Handle is the address of each service, and a 32-bit integer is seen on the interface. But in fact, the ultimate limit of handle in a single service is within 24bit, which is 16M. The high 8 bits are reserved for inter-cluster communication. Finally, we allow 255 Skynet nodes to be deployed on different machines for collaboration. Each skynet node has a different ID. This is known as the Harbor ID. ”
"When each message packet is generated, the Skynet framework encodes its harbor ID to the high 8 bits of the source address. In this way, all the service modules in the system have different addresses. From a digital address, it is easy to identify whether the message is a remote message or a local message. ”
"When all message packets are sent, Skynet recognizes that this is a remote message packet and forwards it to the harbor service. The Harbor service establishes a TCP connection to all harbor services within other Skynet nodes it recognizes. ”
"Skynet currently supports a global name service that can send a message packet to a service with a specific name. This service does not have to exist in the current Skynet node. In this way, we need an organization to be able to synchronize these global names. To do this, I realized a service called Master. Its role is to broadcast synchronization of all the global names, as well as the address of the Skynet node that joins in. ”
5. Inter-service broadcasting:
Broadcast packet reference count: "Skynet identifies whether the message type is PTYPE_MULTICAST
, then has a different life-time management policy, and the multicast packet is given to the multicast service for processing. ”
The multicast service does not solve the problem of grouping services grouped on different cluster nodes. That is, the members within each group must be within the same system process. This can greatly simplify the design. Users can have different service handle belong to a group number. Ask Skynet for this group number corresponding to the handle. Sending a message to the handle of this group is equivalent to sending a message to all handle in the group. ”
Cross-process grouping: "First, provide a simple, C-written service called Tunnel. It can send messages to it unconditionally and forward it to another handle. This forwarding handle can be on a different Skynet node. "," I wrote a global grouping manager with LUA, coordinating the creation of groupings of the same group names on different nodes. Then it is enough to connect the same group on different nodes with the tunnel service. ”
6. Process Control for basic services:
"Skynet provides a skynet_command
C API called the Unified Portal for basic services. It takes a string argument and returns a string result. You can be seen as a text protocol. However, it is guaranteed that the skynet_command
current service thread will not be cut out during the call, leading to unpredictable state changes. ”
7. Message Scheduling
"At Skynet startup, a number of worker threads (configurable quantities) are created, and they are constantly fetching a secondary message queue from the main message line, taking a message from the secondary queue and invoking the callback function of the corresponding service. In order to invoke fairness, only one message at a time is processed, not all messages are consumed (although that is more locally efficient, because the number of query service entities is reduced, and the number of times the main message queue enters and exits), so that no service is starved to death. ”
From the business requirements, the core is that each time the business processing will be the same data block write, how, if the service will be synchronized between the coordination, then the single service polling is better than the way to handle.
My business needs are chat rooms. Public chat room, start multiple services, each service needs to do 2 things: 1. Broadcast to other users when a broadcast message is received-the user information is saved in the process. 2. Write a broadcast message to a cache queue. On this basis, it is necessary to implement a service that periodically persists the new data in the cache queue.
If you use Skynet as the chat server, in order to make full use of the mechanism of message scheduling and Skynet of multi-core utilization, you can use the "Skynet service pool" to handle all the players chat requests.
8. Gate
"It is characterized by listening to a TCP port, accepting incoming TCP connections, and forwarding the data obtained on the connection to the internal Skynet." Gate can be used to eliminate inconsistencies in external packets and skynet internal message packets. "
9. Connection
"Connection is a two-part, partly used to monitor the readable state of different system FD, which is implemented with Epoll. If there is no epoll support environment (such as FreeBSD), it is easy to implement a replacement. Once it receives the data on the connection, it forwards all the data to the other service without any subcontracting. "
"Using the provided LUA module, it is easy to subcontract the data (read a block of bytes of a specified number, or read a line of text ending with a carriage return). Lua's coroutine support makes it easy to suspend a packet when it is incomplete, without interrupting the execution process. "
Ten. Lua Layer
"Lua's coroutine can help us make a logically continuous thread of callback calls that are separated at the C level." When a service written by Lua receives an external request, the corresponding underlying callback function is called and quantitation is forwarded to the LUA virtual machine. The Skynet LUA layer creates a separate coroutine for each request. Once a remote call occurs in the coroutine that handles the request, a message packet is emitted, and coroutine hangs. At the C level, this time the callback function returns normally. In Lua, however, the session of the message packet is recorded, and the session and the suspended Corutine are recorded in a corresponding table. After that, the same session is received in the response packet, and the corresponding Coroutine is awakened to resume . ”
Skynet: Feature Collection