I. Introduction to RPC
1. The distributed
A distributed system is a collection of independent computers (servers)
Disadvantages of traditional single-application architectures:
- Performance scaling is difficult
- It is not conducive to multiple simultaneous development
- Adverse to Upgrade and Maintenance
- The whole system takes up a lot of space
2. RPC
Remote Procedure Call (RPC) refers to Remote Procedure Call. It is a method of communication between processes. It is a technical idea, not a specification. It allows a program to call a procedure or function in another address space (on another machine in the network). It can be simply understood as the communication mode between distributed computers (servers)
Features of RPC:
- Simple: Simple to use and easy to build distributed applications.
- Efficient: The invocation process looks very clear and efficient.
Dubbo framework
Apache Dubbo (incubating) | ˈ d ʌ b goes ʊ | is a high-performance, lightweight open source Java RPC framework, it provides three main core competencies: an interface of remote method invocation (rmi), intelligent fault tolerance and load balancing, and automatic registration and discovery of services. Dubbo is a distributed service framework dedicated to providing high-performance and transparent RPC remote service invocation solutions and service governance solutions.
Liverpoolfc.tv: dubbo.apache.org/zh-cn/
1. Basic architecture
2. Architecture components
- Service Container: Manages service providers.
- Provider: A service Provider that exposes a service. At startup, the service Provider registers its services with the registry.
- Service Consumer: the service Consumer who invokes the remote service. When the service Consumer starts up, it subscribes to the registry for the service it needs. The service Consumer selects one provider from the provider address list and invokes it based on the soft load balancing algorithm.
- Registry: The Registry returns a list of service provider addresses to the consumer. If there are changes, the Registry pushes the change data to the consumer based on the long connection
- Monitor: Service consumers and providers accumulate call times and call time in memory and regularly send statistics to the monitoring center once a minute
3. Call the procedure
(0) The service container is responsible for starting, loading, and running the service provider. (1) Service providers register their services with the registry at startup. (2) At startup, service consumers subscribe to the registry for the services they need. (3) The registry returns the service provider address list to the consumer. If there is any change, the registry will push the change data to the consumer based on the long connection. (4) The service consumer selects one provider from the provider address list to call based on the soft load balancing algorithm. If the call fails, it selects another one to call. (5) Service consumers and providers will accumulate call times and call time in memory and regularly send statistical data to the monitoring center every minute.
4. Agreements supported by Dubbo
Supports multiple protocols: Dubbo, Hessian, RMI, HTTP, WebService, Thrift, memcached, redis.
Dubbo officially recommends using the Dubbo protocol. Dubbo default port 20880:
Three, the simple realization of direct connection
Point-to-point direct connection projects: the consumer accesses the service provider directly, without a registry. The consumer must specify the service provider’s access address (URL). A consumer accesses a fixed service provider directly through a URL address. This URL is going to be the same.
1. Subcontracting, granularity, version
- Subcontracting: It is recommended to put service interfaces, service models, service exceptions, and so on in a common package.
- Granularity: The granularity of service interfaces should be as large as possible. Each service method should represent a function rather than a step of a function. Service interfaces should be divided by service scenarios and abstracted from similar services to prevent interface explosion.
- It is not recommended to use abstract general interfaces, such as Map Query (Map). Such interfaces have no clear semantics (you do not know what to query), which may cause inconvenience in future maintenance.
- Version: Each interface should be defined with a version number to distinguish different implementations of the same interface. For example:
"Dubbo: service interface =" com. XXX. XxxService "version =" 1.0 "/ >
.
Now implement a simple requirement to understand how Dubbo works. Do not use a registry here, through direct connection to complete. The system demand of an e-commerce platform, users purchase goods, through the order system to generate orders; Users access the user information system to view their own information (the order system and the user information system are on two servers, and the part shared by the two systems is placed in a separate project)
2. Common resource projects
Create a New Maven javaSE project and define the interface and entity classes on the project.
3. User information service module
Create a New Maven Web module
(1) Add dependencies and compile plug-ins
<dependencies>
<! Add the public resources module created in step 2 -->
<dependency>
<groupId>com.wkcto.dubbo</groupId>
<artifactId>003-node-interface</artifactId>
<version>1.0.0</version>
</dependency>
<! - for SpringMVC dependence - >
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>4.3.16. RELEASE</version>
</dependency>
<! Spring Framework dependencies -->
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>4.3.16. RELEASE</version>
</dependency>
<! - Dubbo dependence - >
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>2.6.2</version>
</dependency>
</dependencies>
<build>
<plugins>
<! --JDK1.8 plugin -->
<plugin>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.1</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
</plugins>
</build>
Copy the code
(2) Create the implementation class of the interface in the public module
Note: To serialize an entity bean, you need to implement the Serializable interface
(3) Configuration file (service provider)
<dubbo:application/>
: Configures application information- Name: indicates the service name. The current service name is unique
<dubbo:protocol/>
: Configures the registry- Name: Transport Protocol (DuBBO)
- Port: indicates the port number. The port number is used to find the service to access from the service provider. On the same computer, each service (module) corresponds to one port
<dubbo:service/>
: Configures exposed services- Interface: Fully qualified class name of the interface to expose
- Ref: Implementation class of the interface (external service functions of the interface)
- Registry: use N/A for direct, no registry
- Version: If the interface has multiple implementation classes, use this parameter to specify different implementation classes (polymorphic)
- Timeout: Timeout time for invoking the remote service (milliseconds)
- Retries: Sets the number of retries (excluding the first attempt) when an access fails.
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<! The service name must be unique.
<dubbo:application name="005-node-orderservice-provider"/>
<! --dubbo specifies the protocol and port number to use -->
<dubbo:protocol name="dubbo" port="20884"/>
<! Ref: indicates the identity of the interface implementation class. Registry: indicates that no registry is used, and the value is N/A -->
<dubbo:service interface="com.wkcto.dubbo.service.OrderService" ref="orderServiceImpl" registry="N/A"/>
<! The implementation bean of the service interface is declared manually.
<bean id="orderServiceImpl" class="com.wkcto.dubbo.service.impl.OrderServiceImpl"/>
</beans>
Copy the code
(4) Configure Tomcat (web.xml)
In the place where Tomcat is configured in IDEA, set the Tomcat port to 8081 and the IDEA JMX port to 1097 to prevent port conflicts when multiple Tomcat servers are enabled using THE DEBUG mode of IDEA.
Reconfigure the web.xml file:
- Add listeners to global scoped objects, automatically load dubbo configuration files, and create dubbo services
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:orderservice-provider.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
Copy the code
4. Create an order system
The first two steps to create the order system are the same as those in 3
(1) Dubbo configuration file
Similar to step (3) in step 3, you need to change the port number of dubbo, the exposed interface, and the corresponding interface implementation class
(2) Tomcat (web.xml)
Change the Tomcat port and Idea JMX (the port on which the Idea Debug service runs)
5. Create service consumers
(1) Configuration file (Service consumer)
Key steps:
<dubbo:reference/>
: Configures the remote service referenced by the service consumer- Id: indicates the name of the local interface
- Interface: fully qualified interface name of the remote interface
- Url: indicates the URL of the remote interface to be accessed using the Dubbo protocol
- Version: Use this parameter to specify different versions of the same interface (implementation class, polymorphism)
- Registry: “N/A” indicates direct connection
- Timeout: Timeout time for invoking the remote service (milliseconds)
- Retries: Sets the number of retries (excluding the first attempt) when an access fails.
- Check =”true” : false Disables the check. The default is true. If dubbo does not check whether the dependent services are available at startup, an exception will be thrown if the dependent services are not available. If some services do not care, or cyclic dependencies occur and one of them must be started first, you can set this property to false.
<dubbo:application name="006-node-consumer-web"/>
<dubbo:reference id="remoteOrderService"
interface="com.wkcto.dubbo.service.OrderService"
url="dubbo://localhost:20884"
registry="N/A"/>
<dubbo:reference id="remoteAddressService"
interface="com.wkcto.dubbo.service.AddressService"
url="dubbo://localhost:20883"
registry="N/A"/>
<bean id="shopService" class="com.wkcto.dubbo.service.impl.ShopServiceImpl">
<property name="orderService" ref="remoteOrderService"/>
<property name="addressService" ref="remoteAddressService"/>
</bean>
Copy the code
(2) Other steps
Once the remote service interface is obtained, it can be used in the current project. The rest of the steps are the same as in the SSM and are omitted here.
4. Registration Center
Dubbo provides several types of registries to choose from:
- Multicast registry: Multicast mode
- Redis Registry: Use Redis as the registry
- Simple registry: Is a Dubbo service. As a registry. Provides the function of finding services.
- Zookeeper Registry: Use Zookeeper as the registry
You are advised to use the Zookeeper registry.
1. How the registry works
2. Configure the zookeeper
Zookeeper is a high performance, distributed, open source distributed application coordination service. Zk for short. Zookeeper translates to animal keeper. You can think of it as a Resource manager or registry in Windows. It’s a tree structure. This tree structure is similar to a standard file system. Each node in the ZooKeeper tree is called a Znode. Like the directory tree of a file system, each node in the ZooKeeper tree can have child nodes. Each node represents a unique service resource. To run Zookeeper, you need to download the Java environment from zookeeper.apache.org/
Configuration steps (the same for Linux and Windows) :
-
Download file zookeeper-3.5.4-beta.tar.gz. Decompress and go to the directory
-
Example Modify the configuration file in zookeeper-3.5.4/conf/. Copy zoo-sample. CFG and rename it zoo.cfg
-
There are several important parameters in the configuration file:
- TickTime: indicates the heartbeat time, in milliseconds. Interval for maintaining heartbeat between Zookeeper servers or between clients and servers. That is, each tickTime sends a heartbeat. Indicates survival status. The default can be
- DataDir: data directory, which can be any directory. The default value is/TMP/zooKeeper. You are advised to create a data directory under the ZooKeeper installation directory. Change the dataDir configuration to /usr/local/zookeeper-3.4.10/data
- ClientPort: specifies the port used by the client to connect to ZooKeeper. The default value is 2181
- Check =”true” : Disables (false) the registry startup check, which checks that the registry exists and is running when services are started by default (true). An error occurs when the registry is not started. General development with, production does not match
-
Zookeeper 3.5.x starts an application server by default and occupies port 8080 by default. Therefore, you need to set the following parameters:
- admin.serverPort=8888
3. Start the ZooKeeper service
- In Windows, use bin/ zsservice. CMD in the ZooKeeper installation directory
- In Linux, run the following command in the zooKeeper installation directory bin (JDK is required in Linux) :
- Start (switch to the bin directory of the installation directory) :
./zkServer.sh start
- Close (switch to the bin directory of the installation directory) :
./zkServer.sh stop
- Start (switch to the bin directory of the installation directory) :
5. Change the project in 3 to use the registry
1. Add a dependency
<! - they are dependent on - >
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
<version>4.1.0</version>
</dependency>
Copy the code
2. Modify the Dubbo configuration file
<dubbo:registry address="zookeeper://localhost:2181"/>
: Configures the ZooKeeper registry- Get rid of all
registry="N/A"
attribute - The service provider does not need to specify the service address through the URL, but obtains the service address through the registry, so it can be deleted
(1) Service providers
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="004-node-userservice-provider"/>
<dubbo:protocol name="dubbo" port="20884"/>
<! -- Use zooKeeper registry -->
<dubbo:registry address="zookeeper://localhost:2181"/>
<! --<dubbo:service interface="com.bjpowernode.dubbo.service.AddressService" ref="addressServiceImpl" registry="N/A"/>-->
<dubbo:service interface="com.bjpowernode.dubbo.service.AddressService" ref="addressServiceImpl"/>
<bean id="addressServiceImpl" class="com.bjpowernode.dubbo.service.impl.AddressServiceImpl"/>
</beans>
Copy the code
(2) Service consumers
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<dubbo:application name="006-node-customer-web"/>
<! -- Added zooKeeper -->
<dubbo:registry address="zookeeper://localhost:2181"/>
<dubbo:reference id="remoteAddressService"
interface="com.bjpowernode.dubbo.service.AddressService" />
<! Delete url and registry-->
<dubbo:reference id="remoteOrderService"
interface="com.bjpowernode.dubbo.service.OrderService"/>
<bean id="shopService" class="com.bjpowernode.dubbo.service.impl.ShopServiceImpl">
<property name="orderService" ref="remoteOrderService"/>
<property name="addressService" ref="remoteAddressService"/>
</bean>
</beans>
Copy the code
3. High availability of Dubbo
High Availability: Generally used to describe a system that is designed to reduce the amount of time that services are not available while maintaining a High degree of Availability of its services.
- Zookeeper is highly available and robust. Zookeeper is down, but the dubbo service that is running can be accessed.
- The breakdown of the monitoring center does not affect the use of the system, but only the loss of some sample data
- The registry can still provide service list queries through caching, but it cannot register new services
- The service provider is stateless. If any service provider breaks down, the service is not affected
- When all service providers go down, the service consumer application becomes unavailable and reconnects indefinitely waiting for the service provider to recover
Vi. Monitoring center
1. Download
Download monitoring Center: github.com/apache/incu… Download here is the source code, you need to manually compile to use.
2. Configure the monitoring center
Dubo-admin-0.0.1 – snapshot. jar\ boot-INF \classes\application-properties file:
3. Run dubo-admin on the management background
Go to the directory where dubo-admin-0.0.1 – snapshot.jar is located. Run the following command:
Java jar dubbo - admin - 0.0.1 - the SNAPSHOT. The jarCopy the code
4. Run the dubo-admin application
1) Start the registry first 2) execute the provider project 3) java-jar dubo-admin-0.0.1 – snapshot. jar Start the Dubbo administration background 4) Enter http://localhost:7001 in the browser address bar Access monitoring Center – console. The data of the monitoring center from registry (they are) (dubbo in the configuration file. The registry. Address = Zookeeper: / / 127.0.0.1:2181).
7. Exceptions encountered
1. Circular dependencies
Error:Cannot build artifact ’07-zk-orderservice:war exploded’ because it is included into a circular dependency (artifact ’07-zk-orderservice:war exploded’, artifact ’04-node-orderservice (1):war exploded’)
- Contains loop dependencies
- Solution process:
- See if there are dependencies between Maven modules in POM.xml
- View File -> Project Structure -> Project Settings -> Artifacts to see if any additional Artifacts appear
2. java.lang.IllegalStateException
java.lang.IllegalStateException: Illegal access: this web application instance has been stopped already. Could not load [org.apache.zookeeper.ZooKeeperTestable]. The following stack trace is thrown for debugging purposes as well as to attempt to terminate the thread which caused the Illegal access………………….
- Cause: The ZooKeeper registry is not enabled
- Solution: Enable the ZooKeeper registry