Every time I attended various conferences or training sessions, I made up my mind to learn English well, but this goal was not fulfilled again and again. Of course, I was busy with work, time was tight, and there was no context ...... It has become a powerful interface, but this time I think of a second method. Although I have not practiced the context of listening, we can first practice the English translation ability, I usually spend a lot of time reading English DOC files. I think there are no obstacles to reading most documents, but this requirement is to translate them,It can be understood and translated completely at two levels.! You can try it if you don't believe it. This time, I was just reading some documents about ice, and I didn't have more detailed Chinese documents for online search, so I decided to translate the architecture part of my official document. You are welcome to give it away!
2.2.1 Introduction
Ice is an object-oriented middleware platform. Basically, this means that ice provides tool, API, and various lib support for building object-oriented CS structured applications. Ice applications are very suitable for use in a variety of environments: the client and server can be implemented in different programming languages, and can run in different operating systems and server architectures, communication between each other can also use various network technologies.
2.2.2 terminology
Each technology creates some unique words in its evolution and maturity. Of course, ice is no exception, but there are very few words that are unique to ice. Compared with new terms, we prefer to use existing terms. If you have used other middleware technologies in the past, such, then you will be very familiar with the following content;
Clients and servers
For an application, the client and server correspond to different parts. Generally, they refer to the specific application parts that play different roles in a request:
- The client can be understood as an active entity. They are responsible for initiating a request service to the server;
- Server can be understood as a passive entity. They are responsible for responding to client requests and providing services;
Generally, the server is not a "pure" server [never initiates a request and only responds to the request]. On the contrary, the server often plays the dual role of the server and the client, they assume the role of the client to satisfy the requests of the original client.
Similarly, the client is not a "pure" client [only responsible for initiating requests but not responding to requests]. On the contrary, the client often plays a dual role. For example, A client may initiate a long request to the server. As part of the request, the client provides a callback [callback] object to the server, the server can notify the client after the operation is completed. In this instance, the client plays the role of the client when the request is initiated, the role of the server is assumed when the client is notified after the server completes execution.
Similar to the above, role swapping is very common in many systems. Generally, CS-type application systems are more accurately described as point-to-point [Peer] systems.
Ice objects
An ice object is a conceptual and abstract entity. Generally, an ice object has the following features:
- It is a local entity or an object in a remote address space that can respond to client requests.
- A single ice object can be instantiated on one server or redundant on multiple servers. Although an object has multiple instances that coexist, but it is still a single ice object.
- Each ICE object has one or more interfaces. interfaces are a set of Operation operations. Clients call interfaces to initiate requests.
- An operation has zero or multiple parameters, and the return value is the same. Both parameters and return values have a specific type [type]. For parameters, they are divided into two types: the input parameter in-parameters is initialized by the client and sent to the server. The output parameter out-parameters is initialized by the server and sent to the client. The returned value is only a special output parameter.
- An ice object has a primary interface that can be different from other objects. In addition, an ice object also provides zero or multiple optional interfaces, which are called facets; the client can select one of the facets of an object to work together.
- Each ICE object has a unique object ID [Object Identity]. An Object ID is used to distinguish it from other objects; the ice object model assumes that the object IDs are globally unique. That is to say, in an ice communication domain, no two objects have the same object IDs. In fact, object identifiers do not necessarily require globally unique identifiers like UUID. You only need to ensure that any two object identifiers do not conflict with each other in your own ice communication domain.
Proxies
To communicate with an ice object, the client must hold the proxy [proxy] of an ice object. The proxy is like a local object for the client address space. For the client, the proxy represents the ice object (which may be a remote object). For an ice object, the proxy is a local ambassador. The proxy in ice is equivalent to the reference in CORBA, ice uses proxy replacement references to avoid confusion, because references already have too many meanings in different programming languages. When the client triggers an operation on the proxy, ice performs the following operations:
- Find the ice object to be communicated;
- If the server where the ice object is located is not running, activate it;
- Activate the ice object on the server;
- Transmit input parameters to the ice object;
- Wait for the server to complete the operation;
- Return the output parameters and return values to the client. An exception is thrown when a problem occurs;
The proxy encapsulates all necessary information to complete the operations in all the above steps. Specifically, the information contained by a proxy includes:
- Address information: allows the client to find the correct server during running;
- Object ID: You can clearly find a specific object on the server;
- Optional facet identifier: determines a specific facet to be associated with the proxy;
Stringified proxies
The information contained in the proxy can be expressed as a string. For example, a string
Simpleprinter: default-P 10000
It is the most readable expression of a proxy. When ice is running, it provides API calling support. It allows a proxy to be converted into a string. On the contrary, it is also possible. This is very useful. For example, you can save the proxy in a database or text file.
Assuming that the client knows the Object ID and address information of an ice object, it can generate a proxy Based on the provided information, just like nothing. In other words, the proxy does not contain any non-transparent information. A client only needs to know the Object ID, address information, and object type (when an operation needs to be triggered ).
Direct proxies
Direct proxy is a type of proxy. It embeds the Object ID and the address information that the server runs. The complete address information includes two parts:
- Protocol identifier, such as TCP/IP or UDP;
- The address specified by the Protocol, such as the host name and port number;
To communicate with the objects following the direct proxy, ice uses the address information in the proxy to contact the server during operation. Then, each time the client initiates a request, the identifier of the object is sent to the server.
Indirect proxies
There are two forms of indirect proxy: it only provides the Object ID, or it only provides the Object Adapter identifier that matches the Object ID ]. An object that can be accessed only through its object ID becomes a well-known object. For example, a string
Simpleprinter
Is a valid proxy for a well-known object identified as simpleprinter.
An indirect proxy that includes the object adaptation identifier has the following stringized form:
Simpleprinter @ printeradapter
All objects adapted to this object can be accessed through this proxy, regardless of whether the object is a well-known object.
Note: The indirect proxy does not contain the address information. To determine the correct server, the agent information is transmitted to the location service when the client is running. In turn, the location service uses the Object ID or the object adaptation ID as the keyword, query the list containing the server address information and return the correct server address information to the client. In this way, the client will know how to communicate with the server.
The above process is similar to DNS [Domain Name Service] to convert a domain name to an IP address. When we use a domain name, such as opening www.zeroc.com to request a Web page, the host name is first resolved to an IP address in the background. Once the correct IP address is obtained, it can be directly used to connect to the correct server. For ice, except for finding the corresponding protocol address pair from an object ID or an object adaptation ID, The ing is similar to others; when the client is running, it knows how to contact the positioning service through the configuration information, just as the web browser knows which DNS to use through configuration.
Direct versus indirect binding
The process of parsing the relevant information from the proxy into a protocol address pair is called binding. As you can imagine, direct binding is for direct proxy, and indirect binding is for indirect proxy.
The main advantage of indirect binding is that it allows us to change the server address without changing the agent held by the client. In other words, direct proxy can avoid locating additional queries on the server, but when the server changes to another machine, the direct proxy becomes invalid. On the other hand, indirect proxy can continue to work, even if we move or change the server.
Fixed proxies
A fixed proxy is also a type of proxy. It is bound to a specific connection. Unlike an address information or an adapter name, a fixed proxy contains a connection handle [handle ]. The connection handle is valid only when the connection is opened. Once the connection is closed, the proxy is no longer valid. The fixed proxy cannot be [canceled aled], that is, they cannot be passed as parameters during operation calls. Fixed proxies are often used for bidirectional communication [bidireal al communication], so that the server can not re-open a new connection, call back the client directly.
Routed proxies
The routing proxy directs all requests to a specific target object instead of directly sending a call request to an actual object. The routing proxy is very useful for implementing services similar to glacier2, it allows the client and server to communicate with each other under firewall protection.
Replication
Replication is a necessary condition for the Object Adapter to be valid at multiple addresses. The purpose of replication is to provide redundancy for the same server running on multiple different servers. Even if one of the servers has a problem, the server is still valid on other servers.
In particular, the use of replication means that the client can access an object through an address, or return the same result through other addresses; these objects are either stateless, either their implementation is designed to be synchronized with the database, because the States of each object must be consistent.
When a proxy specifies multiple addresses for an object, ice provides limited support. During connection initialization, ice randomly selects one of the address spaces when it is running, when the connection fails, the system tries to connect the connection with another address during running. For example, consider the following Proxy:
Simpleprinter: TCP-H server1-P 10001: TCP-H server2-p 10002
The proxy indicates that the object is identified as simpleprinter, the object using the TCP protocol, and the two addresses server1 and server2 are valid; for users or system administrators, the most important thing is to ensure that the server actually runs on a server with different port numbers.
Replica groups
In addition to the proxy-based replication mentioned above, ICE also provides a more useful form called the replication cluster replica groups, which needs to be used to locate the service.
A replication cluster has a unique identifier and is composed of any number of object adapters. An Object Adapter can only be a member of up to one replication cluster, such an adapter is called the replicable Object Adapter [replicated Object Adapter ].
After a replication cluster is determined, its identifier can be used in the indirect proxy to replace the adapter identifier. For example, a replication cluster identified as printeradapters can be used in the following Proxy:
Simpleprinter @ printeradapters
The replication cluster is regarded as a virtual Object Adapter by the locating service. when parsing an indirect proxy that contains the duplicate cluster ID, the locating service behavior is an implementation detail. For example, a location service can decide to return the address information of all object adapters in the cluster, at this time, the client will randomly select one of the addresses in the limited replication mode discussed earlier. Another possibility is that only one unique address is returned for the locating service, such a decision depends on the heuristic method.
Regardless of how the service resolution and replication cluster is located, the key outcome is indirect: In the binding process, the service can be positioned as a man-in-the-middle to add more intelligence.
Servants
As we mentioned earlier, an ice object is a conceptual entity with types, identifiers, and addresses, client requests must end with an exact server processing entity. The processing entity can provide specific actions for the Operation call. To put this differently ], A client request must end with the execution of the server code, which is written in a specific programming language and executed through a specific processor.
A server is an artifact that provides the corresponding actual actions when the server is called. A server provides the ontology [substance] for one or more ice objects. In actual situations, A server is only a class instance compiled by a server developer. This instance is registered as a server with one or more ice objects during server running; the method in the class is equivalent to the operation in the interface provided by the ice object, and provides specific behavior for each operation.
A single server can be attached to a single ice object or multiple ice objects at the same time. If it is the former, the ice objects attached to the server are clear in the server; if it is the latter, the server will be provided according to the ice Object ID for each request, so that it can decide which object will be attached during the request.
In contrast, a single ice object can have multiple servers. For example, we may create a proxy for an object, which has different addresses for different servers; in this case, we have two servers, each containing a server for the same ice object. When the client requests an operation for this ice object, when the client runs, a request is sent directly to a specific server. In other words, multiple servers of a single ice object allow us to build a redundant system: when the client tries to send a request to a server during running, if the request fails, you can send the request to another server. When the second attempt fails, the client application receives an error message returned by the server.
At-most-once Semantics
Ice supports up to one [at-most-once] Syntax: The ice runtime does its best to distribute requests to the correct destination, depending on the exact environment, he may retry a failed request. Ice guarantees that he or she can either distribute a request. If he cannot distribute the request, at this time, he will explicitly tell the client a proper exception. For a request, no [under no circumstances] will be distributed twice, that is, retry is initiated only when the previous request failed is clearly known (note: the triggering of built-in addressing information through UDP is an exception. In that case, duplicate UDP packets may cause violation of up to one semantics ).
It is very important to support up to one semantics, because they can ensure that operations other than "idempotent" can be safely used; the so-called "Ming" operation means that an operation returns the same result even if it is executed multiple times; for example, x = 1; Is a Ming operation; even if we execute twice, the returned results are the same as those of the previous one. On the other hand, X ++; this operation is not like the other: If we execute this operation twice, the result is different from the result returned for the first time.
If we do not support up to one semantics, we can build a more robust distributed system for network failures. However, the real system needs to support non-ming and other operations, so it is necessary to have at most one semantics, even if they reduce the robustness of the system. Ice allows you to identify a specific operation as "Ming". For such operations, ice uses a more invasive error recovery mechanism than non-ming operations.
Synchronous Method Invocation
By default, the request Distribution Model of ice is synchronous Remote Procedure Call [Remote Procedure Call]: At this time, the Operation call behavior is like a local procedure call, that is, the client thread is suspended until the call is complete.
Asynchronous Method Invocation
ICE also knows that the Asynchronous Method triggers [AMI]: The client can call an operation asynchronously, that is, the client uses a proxy to trigger an operation as usual, but apart from passing common parameters, you also need to pass the callback object, and the client will return immediately when triggered. Once the operation is complete, the server triggers the method in the callback object initially passed in by the client during running, and then transmits the operation result to the callback object (if the processing fails, the exception information is transmitted to the callback object ).
The server cannot identify asynchronous triggering of requests in synchronous or other ways. The server only knows that the client has triggered an operation on an object.
Asynchronous Method dispatch
AMD is the AMI of the server. For the default synchronous distribution, the server directly locates the application code in the server during running to respond to the triggered operation. During the operation, A running thread on the server is fully occupied and released when the operation is completed.
For Asynchronous distribution [amd], when an operation on the client is triggered to reach the server, the application code of the server is notified. However, the code in the AMI is different from the code in the AMI to process requests immediately, the server application can choose to delay the processing of the request, so that it releases the execution thread for the request. At this time, the server application code can do whatever he wants. Finally, once the operation result is available, the application code calls the API to notify the server that the sent request has been processed, then, the result of the operation is returned to the client when ice is running.
AMD is very useful. For example, the server provides a very time-consuming operation to the client, or a server operation needs to asynchronously read data from other additional data sources and return it to the client. For synchronous distribution [SD ], each client must always wait for the data returned by the server's execution thread. Obviously, this method is not very scalable for many clients. For Asynchronous distribution, thousands of clients can trigger a request for the same operation, but it does not occupy any execution thread of the server.
Another use case of AMD is: when an operation is completed and the operation result is returned to the client, the server must continue to execute the thread to do other tasks, for example, execute cleanup or update the persistent layer storage.
Synchronous and asynchronous distribution are completely transparent to the client. The client cannot tell the server whether to process a request in synchronous or asynchronous mode.
Oneway Method Invocation
The client can call an operation through a one-way request. One-way invocation supports the "Best Effort" syntax. for one-way invocation, the client passes the request to the local transport during runtime, as long as the request is recorded by the local transport buffer, the client request is completed. The actual trigger request is then sent asynchronously by the operating system. For one-way triggering, the server does not respond, that is to say, the traffic is only sent from the client to the server, but not from the server to the client.
One-way requests are unreliable. For example, if the target object does not exist, the request is lost. Similarly, this operation may be distributed to a server, however, the operation may fail (for example, the parameter is invalid). Even so, the client still cannot receive any error notifications.
One-way requests can only be applied to operations that do not have a response, output parameters, or user-level exceptions.
For the application code on the server side, one-way requests are transparent, that is, there is no way to distinguish two-way calls initiated from a one-way request.
One-way requests are only valid for target objects that provide stream-based transmission protocols (such as TCP/IP/SSL.
Note: Even if one-way requests are sent through the stream-based transmission protocol, they may be out of order when being processed on the server; this is because each call is distributed in the thread where it is located; even if the request arrives at the server and is sorted during initialization, that does not mean that they will be processed in that order-the abnormal behavior of the thread call may cause a one-way request to be completed earlier than another one-way request that arrived earlier than him.
Batched oneway Method Invocation
Each one-way request sends an independent message to the server. for a series of short messages, the cost of doing so is quite high: because each message client and server must be switched between the user mode and the kernel mode when running, each message will bring the cost of flow control and message validation at the network level.
Batch One-Way request [batched oneway invocations] allows a series of one-way requests to be sent in a single message: each time a batch one-way operation is triggered, the request will be cached when the client is running, once you accumulate all the one-way requests to be sent, you can call an independent API to send all the requests at a time; then, when the client is running, All cached requests are sent to the server in a message, and the server receives all trigger requests in the form of a message; this avoids repeated kernel switching between the client and the server, making it easier to transmit over the network, because a large message body is much more efficient than many small message bodies.
A single request in one batch of unidirectional information is distributed by a separate thread in the order they are added to the batch. This ensures that one batch of unidirectional information is ordered when it is processed by the server.
Batch One-way requests are particularly useful for message services, such as icestorm.
Datemediinvocations
A data packet request has a similar "Best Effort" syntax as a one-way request. However, the data packet request object uses UDP as the transmission protocol, while a one-way request uses TCP/IP.
Like one-way requests, data packet requests also require no return value, output parameters, or user-level exceptions. Data Packet requests trigger an operation through the UDP protocol, as long as the local UDP stack receives a message, the operation is returned. The actual operation call is asynchronously sent by the network stack in the background.
Packet requests are also unreliable, just like one-way requests.
Unlike one-way requests, packet requests have many additional Error Descriptions:
Some requests may be lost at the network layer because of the unreliable delivery of UDP packets. For example, if three operations are triggered in turn, the middle operation may be lost; similar things cannot occur in one-way requests, because they are distributed based on the connection transmission protocol, and individual requests cannot be lost.
Individual requests may arrive out of order. This is also caused by UDP. Because each request is sent as a separate data packet, data packets may be transmitted through different paths on the network, in this way, the order of request arrival may be different from the order in which they are sent.
Packet requests are very suitable for sending small messages in LANs, And the loss rate is very low. They are also suitable for applications with lower latency and higher reliability, such as fast and interactive applications; finally, packet requests can be used to group messages to multiple servers at the same time.
Batched dataininvocations
For batch one-way requests, batch packet requests allow the collection of many requests in the buffer, and then use the API to send the data in the entire buffer as a packet, and then clear the buffer; batch Data Packets reduce repeated system calls and allow the underlying network to run more effectively. However, batch packet requests are only useful when the batch message capacity does not exceed the network protocol data unit PDU. If the size of a batch data packet is too large, it will be split into multiple data fragments, one or more data fragments may be lost, resulting in the loss of the entire batch message. However, one thing is guaranteed, that is, all requests in a batch data packet are either distributed, or they are not distributed. It is impossible to lose a request in a batch.
Batch data packets on the server use a separate thread to distribute each batch of requests. This ensures that each request in a batch is executed in an orderly manner, it is impossible to re-Sort requests on the server.
Run-Time exceptions
Any operation call may cause a runtime exception. A runtime exception is predefined by ice runtime and overwrites common errors, for example, connection failure, connection timeout, and resource allocation failure. For applications, running exceptions are the same as local exceptions, in this way, local Exception Handling in programming languages with exception handling capabilities is beautifully integrated.
User exceptions
User-level exceptions are used to indicate application-specific errors dependent on the client. user-level exceptions can carry arbitrary complex data and be inherited, in this way, the client can easily handle error categories by capturing an exception in the inheritance system.
Properties
Many parameters in the ice runtime can be configured through the properties file; properties is a key-Value Pair [name-value pair], such as ice. default. protocol = TCP; properties are generally stored in text files and parsed at runtime, such as the thread pool size, Trace Level, and other configuration parameters.