SpringBoot cooperates with Dubbo, uses @ Service and @ Reference, and group to implement multiple interfaces.
To upgrade the company's project, it is necessary to implement springBoot + Dubbo and support multiple implementations of one interface. I met several pits, and I'll record them here.
1. Install Zookeeper
stay Official website Download the latest version 3.5.6 (note to download bin package)
- Extract the downloaded compressed package to the corresponding directory
- cd apache-zookeeper-3.5.6-bin/conf/ / / switch to the configuration directory
- MV zoo ABCD sample.cfg zoo.cfg / / change the default profile name
- vi zoo.cfg / / edit the configuration file, customize dataDir, and paste my configuration below
Here you will encounter the first pit: zk starts from 3.5.5, and the package with bin name is the package we want to download, which can be used directly, including the compiled binary package, while the tar.gz package is just the source code, which cannot be used directly. I accidentally dropped the apache-zookeeper-3.5.6.tar.gz package, and an error "error: unable to find or load the main class org.apache.zookeeper.server.quorum.QuorumPeerMain" will be reported at startup.
zoo.cfg
# Interval between heartbeats sent in milliseconds tickTime=2000 # It is used by the cluster. When initializing the connection, the leader can tolerate the maximum number of heartbeat intervals of the client. The default value is 10, which means 10 * 2000 = 20000, Ms. initLimit=10 # It is used by the cluster. During normal communication, if the client exceeds this time interval, there is no heartbeat. syncLimit=5 # Directory where data is saved dataDir=/Users/ouitsu/document/apache-zookeeper-3.5.6-bin/data # Exposed interface clientPort=2181 # New feature of zk3.5, Zookeeper AdminServer, default port is 8080, a batch of pits admin.serverPort=12181
Here is the second pit. The default port of zookeeper admin server of zk conflicts with the default port of Dubbo admin, and an error will be reported: unable to start adminserver, exiting abnormal org.apache.zookeeper.server, which can be solved by defining the port here.
Configuration complete, start zk
- cd to the bin directory of zookeeper
- . / zkserver.sh start
- . / zkserver.sh stop
Start building project
1. producers
The directory structure is as follows:
The provider POM file is as follows
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.uaepay.pay.channel</groupId> <artifactId>dubbo_provider</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dubbo_provider</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>uaepay.cmf.channel</groupId> <artifactId>dubbo_facade</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>io.projectreactor</groupId> <artifactId>reactor-test</artifactId> <scope>test</scope> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.0.RELEASE</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> <repositories> <repository> <id>spring-milestones</id> <name>Spring Milestones</name> <url>https://repo.spring.io/milestone</url> </repository> </repositories> </project>
provider_application:
package com.uaepay.pay.channel.dubbo_provider; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo //Start configuration of dubbo public class DubboProviderApplication { public static void main(String[] args) { SpringApplication.run(DubboProviderApplication.class, args); }
Two production realizations
package com.uaepay.pay.channel.dubbo_provider.service; import com.alibaba.dubbo.config.annotation.Service; // Pay attention to the Service that references dubbo here import org.springframework.stereotype.Component; // Corresponding, use spring's Component import uaepay.cmf.channel.MockResponseService; import uaepay.cmf.channel.vo.User; @Service(group = "mockResponseServiceImpl") // Define group @Component public class MockResponseServiceImpl implements MockResponseService { @Override public User getUserInfo() { User user = new User(); user.setUserName("1111"); return user; } }
package com.uaepay.pay.channel.dubbo_provider.service; import com.alibaba.dubbo.config.annotation.Service;// Using the Service annotation of alibaba.dubbo import org.springframework.stereotype.Component;// Using Spring's Component annotation import uaepay.cmf.channel.MockResponseService; import uaepay.cmf.channel.vo.User; @Service(group = "mockResponseServiceImpl2") //Define group @Component public class MockResponseServiceImpl2 implements MockResponseService { @Override public User getUserInfo() { User user = new User(); user.setUserName("222222"); return user; } }
application.properties
dubbo.application.name=dubbo-provider-service dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.protocol.port=20782 dubbo.protocol.dispatcher=message dubbo.protocol.threadpool=fixed dubbo.protocol.threads=200 server.port=8871
2. consumers
The directory structure is as follows:
pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.2.0.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <groupId>com.uaepay.pay.channel</groupId> <artifactId>dubbo_consumer</artifactId> <version>0.0.1-SNAPSHOT</version> <name>dubbo_consumer</name> <description>Demo project for Spring Boot</description> <properties> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>com.alibaba.spring.boot</groupId> <artifactId>dubbo-spring-boot-starter</artifactId> <version>2.0.0</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <scope>runtime</scope> <optional>true</optional> </dependency> <dependency> <groupId>uaepay.cmf.channel</groupId> <artifactId>dubbo_facade</artifactId> <version>1.0-SNAPSHOT</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.101tec</groupId> <artifactId>zkclient</artifactId> <version>0.10</version> </dependency> <dependency> <groupId>org.apache.zookeeper</groupId> <artifactId>zookeeper</artifactId> <version>3.4.12</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> <version>2.2.0.RELEASE</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> <exclusions> <exclusion> <groupId>org.junit.vintage</groupId> <artifactId>junit-vintage-engine</artifactId> </exclusion> </exclusions> </dependency> <dependency> <groupId>com.alibaba</groupId> <artifactId>fastjson</artifactId> <version>1.2.28</version> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> </plugin> </plugins> </build> </project>
ConsumerApplication:
package com.uaepay.pay.channel.dubbo_consumer; import com.alibaba.dubbo.config.spring.context.annotation.EnableDubbo; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; @SpringBootApplication @EnableDubbo public class DubboConsumerApplication { public static void main(String[] args) { SpringApplication.run(DubboConsumerApplication.class, args); } }
Consumer's implementation class
package com.uaepay.pay.channel.dubbo_consumer.service; import com.alibaba.dubbo.config.annotation.Reference;// Using Dubbo's reference to get the corresponding implementation import com.alibaba.fastjson.JSON; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import uaepay.cmf.channel.MockResponseService; import java.util.LinkedHashMap; import java.util.TreeMap; @RestController @RequestMapping("/test") public class MockServiceImpl { @Reference(group = "mockResponseServiceImpl")//Corresponding definition group private MockResponseService mockResponseServiceImpl; @Reference(group = "mockResponseServiceImpl2")// Corresponding definition group private MockResponseService mockResponseServiceImpl2; @RequestMapping("/getUserInfo") public void getUserInfo(){ System.out.println("The details obtained are..."+JSON.toJSONString(mockResponseServiceImpl.getUserInfo())); } @RequestMapping("/getUserInfo1") public void getUserInfo11(){ System.out.println("The details obtained are..."+JSON.toJSONString(mockResponseServiceImpl2.getUserInfo())); } }
application.properties
dubbo.application.name=dubbo-consumer-service dubbo.registry.address=zookeeper://127.0.0.1:2181 dubbo.consumer.check=false server.port=8862
facade package
The project structure is as follows:
pom file
<?xml version="1.0" encoding="UTF-8"?> <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> <modelVersion>4.0.0</modelVersion> <groupId>uaepay.cmf.channel</groupId> <artifactId>dubbo_facade</artifactId> <version>1.0-SNAPSHOT</version> <name>dubbo_facade</name> <url>http://www.example.com</url> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <maven.compiler.source>1.7</maven.compiler.source> <maven.compiler.target>1.7</maven.compiler.target> </properties> <dependencies> <dependency> <groupId>junit</groupId> <artifactId>junit</artifactId> <version>4.11</version> <scope>test</scope> </dependency> <dependency> <groupId>org.projectlombok</groupId> <artifactId>lombok</artifactId> <optional>true</optional> </dependency> <dependency> <groupId>commons-lang</groupId> <artifactId>commons-lang</artifactId> <version>2.4</version> </dependency> </dependencies> <build> <pluginManagement> <plugins> <plugin> <artifactId>maven-clean-plugin</artifactId> <version>3.1.0</version> </plugin> <plugin> <artifactId>maven-resources-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-compiler-plugin</artifactId> <version>3.8.0</version> </plugin> <plugin> <artifactId>maven-surefire-plugin</artifactId> <version>2.22.1</version> </plugin> <plugin> <artifactId>maven-jar-plugin</artifactId> <version>3.0.2</version> </plugin> <plugin> <artifactId>maven-install-plugin</artifactId> <version>2.5.2</version> </plugin> <plugin> <artifactId>maven-deploy-plugin</artifactId> <version>2.8.2</version> </plugin> <plugin> <artifactId>maven-site-plugin</artifactId> <version>3.7.1</version> </plugin> <plugin> <artifactId>maven-project-info-reports-plugin</artifactId> <version>3.0.0</version> </plugin> </plugins> </pluginManagement> </build> </project>
Entity class
package uaepay.cmf.channel.vo; import java.io.Serializable; public class User implements Serializable { private String userName; public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } }
Interface
package uaepay.cmf.channel; import uaepay.cmf.channel.vo.User; public interface MockResponseService { public User getUserInfo(); }
Operation item
Start provider
Socket connection established to 127.0.0.1/127.0.0.1:2181, initiating session Session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0x100000dd3c5000c, negotiated timeout = 30000
The successful printing indicates that the producer has registered successfully. If it does not appear, check whether the dependency of com.101tec.zkclient has not been introduced, or whether zk has started successfully.
Start Consumer
<dubbo:reference object="com.alibaba.dubbo.common.bytecode.proxy0@3da222de" singleton="true" interface="uaepay.cmf.channel.MockResponseService" uniqueServiceName="mockResponseServiceImpl/uaepay.cmf.channel.MockResponseService" generic="false" group="mockResponseServiceImpl" listener="" filter="" id="uaepay.cmf.channel.MockResponseService" /> has been built. <dubbo:reference object="com.alibaba.dubbo.common.bytecode.proxy0@4aae626d" singleton="true" interface="uaepay.cmf.channel.MockResponseService" uniqueServiceName="mockResponseServiceImpl2/uaepay.cmf.channel.MockResponseService" generic="false" group="mockResponseServiceImpl2" listener="" filter="" id="uaepay.cmf.channel.MockResponseService" /> has been built.
Print this successfully to prove that the consumer configuration is successful.
If the < Dubbo: reference singleton = "true" interface = "uaepay. CMF. Channel. Mockresponseservice...... / > is printed and the null pointer is accessed, when the print parameter does not contain the object, the consumer does not receive the producer's proxy object. There are two places to check:
- Does the dependency include com.101tec.zkclient?
- Whether the property dubbo.consumer.check=false is added to application.properties
Add: Dubbo admin
dubbo provides background management of dubbo. Download on github , pull to the local project structure as follows:
There are two important sub modules: Dubbo admin server and Dubbo admin UI.
-
Dubbo-admin-server:
- Default port 8080
- It is a springboot project, which can be started directly.
-
Dubbo-admin-ui:
- npm is required. Where npm is not installed
- cd to Dubbo admin UI path, npm install installation depends on
- Depending on the installation, npm run dev
- Run successfully opened http://localhost : 8081
If you don't understand the specific steps, you can check readme.md in the project (also in the sub module), which is written in detail.
So far, it's done!