使用zookeeper作为注册中心搭建Dubbo+SpringBoot 微服务Demo,我们实际项目还有一些zookeeper的监控,但总的差距不大。希望对初学者有一定帮助。
在linux中搭建zookeeper可以参考这篇文章,https://blog.csdn.net/She_lock/article/details/100133782
一,首先创建springBoot项目,生成写生产者和消费者的共同依赖jar包,在pom文件中对需要的组件进行配置。
1,maven配置如下,注意,这里使用的dubbo版本是2.5.3,是因为在使用高版本时遇到了一些问题,这些问题我没有找到原因,所以使用了2.5.3版本
<?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.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.userFacade</groupId>
<artifactId>usersystem</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>userFacade</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-native.version>0.9.1</spring-native.version>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<!--引入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>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
</dependency>
</dependencies>
<build>
<finalName>com-example-userFacade</finalName>
<plugins>
<!-- 解解决maven update project 后版本降低为1.5的bug -->
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2,编写提供服务的service方法,需要注意的是,@Service注解使用的是com.alibaba.dubbo.config.annotation.Service,是dubbo中的类
package com.example.userFacade.service;
import com.alibaba.dubbo.config.annotation.Service;
@Service
public interface MyService {
String getData(String name);
}
3,运行命令 mvn clean, mvn install, 将这个jar打包到本地仓库中,提供依赖给需要的其他项目。
二,新建springboot项目,编写生产者,提供服务。
1,pom文件的配置如下
<?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.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.userService</groupId>
<artifactId>userservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>com.example.userFacade</groupId>
<artifactId>usersystem</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--引入zookeeper-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2,编写 dubbo-provider.xml 和spring-context.xml
dubbo-provider.xml如下:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
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-2.5.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="testservice" owner="programmer" organization="dubbox"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="192.168.56.101:2181" protocol="zookeeper"/>
<!-- 用dubbo协议在38888端口暴露服务 端口不能一样-->
<dubbo:protocol name="dubbo" port="38888" />
<!-- 需要扫描注解的包名 -->
<dubbo:annotation package="com.example.userService.impl" />
<!--告诉注册中心我是谁即暴露服务 interface代表发布的服务类型 ref代表要发布哪个具体服务 timeout超时时间-->
<dubbo:service interface="com.example.userFacade.service.MyService" ref="myServiceImpl" timeout="5000"/>
<!-- 和本地bean一样实现服务 -->
<bean id="myServiceImpl" class="com.example.userService.impl.MyServiceImpl" />
</beans>
spring-context.xml如下:
<?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"
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.xsd"
default-autowire="byName" default-lazy-init="false">
<!-- 采用注释的方式配置bean -->
<context:annotation-config/>
<!-- 配置要扫描的包 -->
<context:component-scan base-package="com.example.userService.impl"/>
<import resource="classpath:spring/dubbo-provider.xml"/>
</beans>
3, 启动类的编写,这里注意,通过ClassPathXmlApplicationContext启动项目。
并且需要启动线程保持阻塞状态,不然项目启动完就自动关闭了,不再提供服务
package com.example.userService;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.support.ClassPathXmlApplicationContext;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
try {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:spring/spring-context.xml");
context.start();
} catch (Exception ex) {
System.out.println("== DubboProvider context start error:");
}
synchronized (DemoApplication.class) {
while (true) {
try {
//需要启动线程保持阻塞状态,不然项目启动完就自动关闭了,不再提供服务
DemoApplication.class.wait();
} catch (InterruptedException ex) {
System.out.println("== synchronized error:");
}
}
}
}
}
4,服务service的实现类的编写 。
package com.example.userService.impl;
import com.example.userFacade.service.MyService;
public class MyServiceImpl implements MyService {
@Override
public String getData(String name) {
return ">>>>>>>>>>>>>调用了方法>>>>>>>>>>>>>>" + name ;
}
}
5,启动main方法,就可以提供服务了
在zookeeper中可查询到启动的项目已经注册进去了
运行zookeeper命令,其中192.168.56.101:2181是zookeeper的地址和端口: ./zkCli.sh -server 192.168.56.101:2181
运行zookeeper命令,其中com.example.userFacade.service.MyService是自己暴露的服务:ls /dubbo/com.example.userFacade.service.MyService/providers
结果如下:
三, 新建springboot项目编写消费者 ,因为是web项目需要配置spring-boot-starter-web,提供调用。
1,pom文件配置如下:
<?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.4.4</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.example.userconsumer</groupId>
<artifactId>userconsumer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>com.example.userFacade</groupId>
<artifactId>usersystem</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
<!--引入zookeeper-->
<dependency>
<groupId>com.github.sgroschupf</groupId>
<artifactId>zkclient</artifactId>
<version>0.1</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.10</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
2,配置dubbo-comsumer.xml
<?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.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd"
default-autowire="byName" default-lazy-init="false">
<!--扫描注解-->
<context:component-scan base-package="com.example.userconsumer.controller"/>
<!--找到注册中心,告诉他你想要什么服务-->
<!--我是谁-->
<dubbo:application name="service-consumer"/>
<!--找到注册中心-->
<dubbo:registry address="192.168.56.101:2181" protocol="zookeeper" />
<!--告诉他你要什么-->
<dubbo:reference interface="com.example.userFacade.service.MyService" id="myService" check="false"
protocol="dubbo"/>
</beans>
3,编写springboot配置文件,引入dubbo-comsumer.xml
package com.example.userconsumer.config;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.ImportResource;
@Configuration
@ImportResource({"classpath:dubbo/dubbo-comsumer.xml"})
public class DubboConfig {
}
4, 编写消费者,进行消费
package com.example.userconsumer.controller;
import com.example.userFacade.service.MyService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.ResponseBody;
@Controller
public class MyContrller {
private static final Log logger = LogFactory.getLog(MyContrller.class);
@Autowired
private MyService myService;//注入服务接口的实例
@ResponseBody
@RequestMapping("/getData")
public String getData(String name){
logger.info(">>>>>>>>>>>>>>进入了方法");
String data = myService.getData(name);
logger.info(">>>>>>>>>>>>>>方法执行完毕");
return data;
}
}
5,启动main方法,进行web调用。
package com.example.userconsumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class DemoApplication {
public static void main(String[] args) {
SpringApplication.run(DemoApplication.class, args);
}
}
6,成功调用,结果如下: