Spring Boot+Dubbo+Maven+ZK Build Enterprise Distributed Micro Services

Keywords: Dubbo Spring Maven xml

Service Registry

Service registry can achieve service external unification through specific protocols. Dubbo mainly provides the following types of service registries:

  • Multicast Registry
  • Zookeeper Registry
  • Redis Registry
  • Simple Registry

In this paper, ZK is used as the service registry, and the construction of ZK environment is not introduced here.

Parent

The Maven Parent module is mainly used to integrate Spring Boot and some common jar s. The code is as follows

<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>com.huang</groupId>
	<artifactId>com.huang.parent</artifactId>
	<version>0.0.1-SNAPSHOT</version>
	<packaging>pom</packaging>
	<parent>
		<groupId>org.springframework.boot</groupId>
		<artifactId>spring-boot-starter-parent</artifactId>
		<version>1.4.2.RELEASE</version>
	</parent>
	<properties>
		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
		<java.version>1.8</java.version>
	</properties>
	<dependencies>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-web</artifactId>
		</dependency>
		<dependency>
			<groupId>org.springframework.boot</groupId>
			<artifactId>spring-boot-starter-tomcat</artifactId>
			<scope>provided</scope>
		</dependency>
		<dependency>
			<groupId>com.alibaba</groupId>
			<artifactId>dubbo</artifactId>
			<version>2.5.3</version>
			<exclusions>
				<exclusion>
					<groupId>org.springframework</groupId>
					<artifactId>spring</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
		<dependency>
			<groupId>com.101tec</groupId>
			<artifactId>zkclient</artifactId>
			<version>0.10</version>
			<exclusions>
				<exclusion>
					<groupId>org.slf4j</groupId>
					<artifactId>slf4j-log4j12</artifactId>
				</exclusion>
			</exclusions>
		</dependency>
	</dependencies>
	<build>
		<plugins>
			<plugin>
				<groupId>org.apache.maven.plugins</groupId>
				<artifactId>maven-compiler-plugin</artifactId>
				<configuration>
					<source>${java.version}</source>
					<target>${java.version}</target>
					<encoding>UTF-8</encoding>
					<excludes>
						<exclude>**/*.svn</exclude>
					</excludes>
				</configuration>
			</plugin>
			<plugin>
				<groupId>org.springframework.boot</groupId>
				<artifactId>spring-boot-maven-plugin</artifactId>
			</plugin>
		</plugins>
	</build>
</project>

Service Provider

In the construction of enterprise-level projects, service providers'interfaces are usually open to the outside world, but the specific implementation is not visible to the outside world, and service consumers do not need to care about the realization of services. This paper uses com.huang.provider module to declare the service interface. pom.xml:

<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>
	<artifactId>com.huang.provider</artifactId>
	<groupId>com.huang</groupId>
    <version>0.0.1-SNAPSHOT</version>
</project>

Service Statement:

/**
 * Order service
 * @author AbeJeffrey
 *
 */
public interface  OrderServiceProvider {
	/**
	 * Query order quantity by type
	 * @param type
	 * @returne
	 */
	public Integer getOrderCount(Integer type) throws Exception;
}

Service Provider Implementation

First look at pom.xml:

<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>
	<parent>
		<groupId>com.huang</groupId>
		<artifactId>com.huang.parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<artifactId>com.huang.provider.impl</artifactId>
	<dependencies>
		<dependency>
			<groupId>com.huang</groupId>
			<artifactId>com.huang.provider</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

From the pom file, com.huang.parent, as the parent module of com. huang. provider. impl, automatically integrates Spring boot capabilities and public jar s. In addition, com.huang.provider.impl relies on com.huang.provider, because the services defined in com.huang.provider are implemented here by com.huang.provider.impl.

Service implementation source code:

@Component
public class OrderServiceProviderImpl implements OrderServiceProvider{
	private AtomicLong  counter=new AtomicLong(0L);
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Override
	public Integer getOrderCount(Integer type) throws Exception{
		/**
		 * Simple Implementation of Interface Call Counter
		 */
		counter.getAndIncrement();
		logger.info("-------------------total call "+counter.get()+" times!!!-------");
		if(null==type){
			throw new Exception("type is null!");
		}
		if(type==1){
			return 10;
		}
		else if(type==2){
			return 100;
		}else{
			return 0;
		}
	}
}

dubbo Service Exposure

Configure the Dubbo service in context-dubbo-provider.xml with the following code:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd 
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
	
	<dubbo:application name="order_provider" owner="order_provider"/> 
	<!-- Use zookeeper Registry Exposure Service Address -->  
    <dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.1:2182,127.0.0.1:2183" />  
  
    <!-- use dubbo Protocol Exposure Service at Port 20880 -->  
    <dubbo:protocol name="dubbo" port="20880" />  
  
    <!-- Declare service interfaces that need to be exposed -->  
    <dubbo:service interface="com.haung.provider.OrderServiceProvider"  
        ref="orderServiceProviderImpl" />  
	
</beans>

Startup service

//Automatic scanning of components in com.huang package
@ComponentScan(basePackages = {
	    "com.huang"
	})
@SpringBootApplication
//Load configuration file
@ImportResource(locations = { "classpath*:spring/context-*" })
public class Application extends WebMvcConfigurerAdapter {
	private static Logger logger = LoggerFactory.getLogger(Application.class);
    public static void main(String[] args) throws ClassNotFoundException {
        SpringApplication.run(Application.class, args);
        logger.info("------------------start success!!!---------------------------");
    }
}

Application is the startup entry for the Spring Book project. The service implementation module is completed.

Note: To start multiple Spring Boot projects locally at the same time, you need to declare the service port in application.properties. Spring Boot uses 8080 by default. The configuration is as follows:

server.port=9001

Service consumers

First look at pom.xml:

<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>
	<artifactId>com.huang.consumer</artifactId>
	<parent>
		<groupId>com.huang</groupId>
		<artifactId>com.huang.parent</artifactId>
		<version>0.0.1-SNAPSHOT</version>
	</parent>
	<dependencies>
		<dependency>
			<groupId>com.huang</groupId>
			<artifactId>com.huang.provider</artifactId>
			<version>0.0.1-SNAPSHOT</version>
		</dependency>
	</dependencies>
</project>

From the pom file, com.huang.parent, as the parent module of com.huang.consumer, automatically integrates Spring boot capabilities and public jar s. In addition, com.huang.consumer relies on com.huang.provider to consume services defined in com.huang.provider in com.huang.consumer.

Service Consumption Configuration

Configure the Dubbo service in context-dubbo-consumer.xml with the following code:

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:context="http://www.springframework.org/schema/context"
	xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
	xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
		http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-4.1.xsd  
        http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
   	
	<dubbo:application name="order-consumer"/>
    <dubbo:registry address="zookeeper://127.0.0.1:2181?backup=127.0.0.1:2182,127.0.0.1:2183" />  
	<dubbo:reference id="orderServiceProvider" interface="com.huang.provider.OrderServiceProvider"/>
	
</beans>

Service Testing

com.huang.consumer writes a controller to implement the call of service, the source code is as follows:

/**
 * Call example: http://localhost:9000/order/get_order_count?type=1
 * @author AbeJeffrey
 *
 */
@Controller
@RequestMapping("/order")
public class TestOrderSeriverBiz {
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Autowired
    private OrderServiceClient  orderServiceClient;
	@RequestMapping("/get_order_count")
    @ResponseBody
    public Integer getOrderCountByCount(Integer type,HttpServletRequest req) {
        try{
        	if(null!=type)
        		return orderServiceClient.getOrderCountByType(type);
            return null;
        }catch (Exception e) {
			logger.error(String.format("orderServiceProvider getOrderCount error. param:%s", type, e));
            return null;
        }
	}
}

OrderService Client, as the client of service access, is mainly for the convenience of local management. The source code is as follows:

@Service
public class OrderServiceClient {
	private Logger logger = LoggerFactory.getLogger(getClass());
	@Resource
	private OrderServiceProvider orderServiceProvider;
	
	public Integer getOrderCountByType(Integer type) {
		try {
			return orderServiceProvider.getOrderCount(type);
		} catch (Exception e) {
			logger.warn(String.format("orderServiceProvider getOrderCount error. param:%s", type, e));
			return null;
		}
	}
}

Start Consumers

@ComponentScan(basePackages = {
	    "com.dianwoba"
	})
@SpringBootApplication
@ImportResource(locations = { "classpath*:spring/context-*" })
public class Application extends WebMvcConfigurerAdapter {
	private static Logger logger = LoggerFactory.getLogger(Application.class);
    public static void main(String[] args) throws ClassNotFoundException {
        SpringApplication.run(Application.class, args);
        logger.info("------------------start success!!!---------------------------");
    }
}

The application.properties configuration is as follows:

server.port=9000

Start the consumer and visit http://localhost:9000/order/get_order_count?type=1 to complete the test.

So far, Spring Boot+Dubbo+Maven+ZK is basically completed to build enterprise-level distributed micro-services.

Abnormal summary

When the startup project has the following exception (no complete exception stack is provided)

Destroy method on bean with name 'org.springframework.boot.autoconfigure.internalCachingMetadataReaderFactory' threw an exception

java.lang.IllegalStateException: ApplicationEventMulticaster not initialized - call 'refresh' before multicasting events via the context: 

The main reason is that Dubbo introduced a low version of Spring, while the Spring version used in this example is 4.3.4.RELEASE. So exclude Spring references in Dubbo.

<dependency>
	<groupId>com.alibaba</groupId>
	<artifactId>dubbo</artifactId>
        <version>2.5.3</version>
	<exclusions>
	       <exclusion>
		        <groupId>org.springframework</groupId>
		        <artifactId>spring</artifactId>
                </exclusion>
      </exclusions>
</dependency>

Construction of Dubbo-Admin Console

The Dubbo console provides service governance and monitoring functions that interested readers can try to build. This article only provides ideas:

1 Download the dubbo source code, compile it yourself, skip the unit test, and use the following commands:

cd dubbo
mvn clean install -Dmaven.test.skip

Once compiled, a war package is generated in the target directory of the dubbo-admin module.

2. Deploy dubbo-admin war packages using tomcat

I use Tomcat 8 dynamic deployment, the steps are as follows:

First, modify tomcat/conf/tomcat-users.xml and add the following code:

 <role rolename="manager-gui"/>
 <user username="tomcat" password="123456" roles="manager-gui"/>

The main purpose is to set the access authority and password of manager.

Then start tomcat, visit http://localhost:8080 to enter the console, click Manager App, enter the login password, select war file, and click deploy to complete the deployment.

dubbo-admin can be found in the Applications list and accessed by clicking.

Note: The default zk address is defined in dubbo-admin. The console accesses the username password and can be modified from dubbo-admin.xml in the WEB-INF directory. Only after the modification is completed, dubbo-admin can be recompiled.

Welcome to point out the errors in this article. If it is helpful to you, please give me some praise and support. Reprinted please indicate the source of the original text.

https://my.oschina.net/7001/blog/906150

Posted by jimmy patel on Sun, 06 Jan 2019 13:09:09 -0800