SpringBoot and Dubbo use @Service and @Reference and group to achieve interface multi-implementation
Company project upgrade, need to implement springBoot + Dubbo, and support the case of multiple implementations of an interface. Encountered a few potholes, recorded here.
1. Install the Zookeeper
Download the latest version 3.5.6 from the official website (note to download the bin package)
- Decompress the downloaded package to the corresponding directory
- CD apache-zookeeper-3.5.6-bin/conf/ / Switch to the configuration directory
- CFG zoo. CFG // Change the name of the default configuration file
- Vi zoo. CFG // Edit the configuration file and customize the dataDir. My configuration is attached below
Here’s the first pitfall: zK starts with 3.5.5, and the bin package is the package we want to download and use directly, which contains the compiled binary package, while the tar.gz package contains only the source code and cannot be used directly. Under the apache – they are not carefully – 3.5.6. Tar. Gz this package, when they start an error “error: cannot find or unable to load the main class org. Apache. Zookeeper. Server quorum. QuorumPeerMain”.
zoo.cfg
# Interval for sending heartbeat in milliseconds
tickTime=2000
How many heartbeat intervals can the leader tolerate when initializing a connection? The default is 10, which means 10*2000=20000 milliseconds
initLimit=10
If the interval is exceeded, the client will not have a heartbeat during normal communication
syncLimit=5
# Directory to save dataDataDir = / Users/ouitsu/document/apache - they are - 3.5.6 - bin/data# Exposed interface
clientPort=2181
# ZK3.5 new feature, Zookeeper AdminServer, default port is 8080, pit batch
admin.serverPort=12181
Copy the code
Zk default Zookeeper AdminServer port conflicts with Dubbo admin default port. Unable to start AdminServer, exiting abnormally org. Apache. The zookeeper. Server, define the port can solve here.
The zK starts after the configuration is complete
- CD Go to the bin directory of ZooKeeper
- . / zkServer. Sh start starts
- . / zkServer. Sh stop stop
2. Start building projects
1. The 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 - the 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 the 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>
Copy the code
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 dubbo configuration
public class DubboProviderApplication {
public static void main(String[] args) {
SpringApplication.run(DubboProviderApplication.class, args);
}
Copy the code
Two production implementations
package com.uaepay.pay.channel.dubbo_provider.service;
import com.alibaba.dubbo.config.annotation.Service; // Note that dubbo's Service is referenced here
import org.springframework.stereotype.Component; // Instead, 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(a) {
User user = new User();
user.setUserName("1111");
returnuser; }}Copy the code
package com.uaepay.pay.channel.dubbo_provider.service;
import com.alibaba.dubbo.config.annotation.Service;// Use the Service annotation of Baba.dubbo
import org.springframework.stereotype.Component;// Use 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(a) {
User user = new User();
user.setUserName("222222");
returnuser; }}Copy the code
application.properties
Dubbo. Application. Name = dubbo - the 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=8871Copy the code
# # # # 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 - the 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 the 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>
Copy the code
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); }}Copy the code
An implementation class for the consumer
package com.uaepay.pay.channel.dubbo_consumer.service;
import com.alibaba.dubbo.config.annotation.Reference;// Use 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")// Define group
private MockResponseService mockResponseServiceImpl;
@Reference(group = "mockResponseServiceImpl2")// Define group
private MockResponseService mockResponseServiceImpl2;
@RequestMapping("/getUserInfo")
public void getUserInfo(a){
System.out.println("The details obtained are..."+JSON.toJSONString(mockResponseServiceImpl.getUserInfo()));
}
@RequestMapping("/getUserInfo1")
public void getUserInfo11(a){
System.out.println("The details obtained are..."+JSON.toJSONString(mockResponseServiceImpl2.getUserInfo())); }}Copy the code
application.properties
Dubbo. Application. Name = dubbo - consumer - service dubbo, registry. Address = zookeeper: / / 127.0.0.1:2181 dubbo.consumer.check=false server.port=8862Copy the code
The 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 the 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>
Copy the code
Entity class
package uaepay.cmf.channel.vo;
import java.io.Serializable;
public class User implements Serializable {
private String userName;
public String getUserName(a) {
return userName;
}
public void setUserName(String userName) {
this.userName = userName; }}Copy the code
interface
package uaepay.cmf.channel;
import uaepay.cmf.channel.vo.User;
public interface MockResponseService {
public User getUserInfo(a);
}
Copy the code
3. Run the project
Start the provider
The Socket connection established to 127.0.0.1/127.0.0.1:2181, Initiating the session session establishment complete on server 127.0.0.1/127.0.0.1:2181, sessionid = 0 x100000dd3c5000c, negotiated timeout = 30000Copy the code
If this is printed successfully, the producer is registered. If not, check to see if the dependencies of com.101tec. zkClient are not introduced, or if zK started successfully.
Start the 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.
Copy the code
Printing this successfully proves that the consumer configuration is successful.
If the print is < dubbo: reference singleton = “true” interface = “uaepay. CMF. Channel. MockResponseService… If the print parameter does not contain object, the consumer does not receive the producer’s proxy object. There are two areas to check:
- Depends on whether com.101tec.zkClient is added
- Application. Properties whether dubo.consumer.check =false is added to the application
4. Attach: dubo-admin
Dubbo provides dubbo backend management, download on Github, pull local project structure is like this:
There are two important submodules: Dubo-admin-server and dubo-admin-UI
- Dubbo – admin – server:
- The default port is 8080
- Is a SpringBoot project, directly start
- Dubbo – admin – UI:
- NPM is required. Click here if NPM is not installed
- CD to dubo-admin-ui, NPM install install dependency
- Dependency installation complete, NPM run dev
- If the operation is successful, open http://localhost:8081
If you don’t understand the specific steps, you can look at the readme.md in the project (also in the submodule), which is very detailed.
At this point, you’re done!