不同服务之间或者多服务之间调用接口的场景实际中会经常遇到,目前市面上解决该问题比较流行的两大框架为dubbo和springcloud。
今天简单的建一个dubbo入门的案例,分为两个小案例一个和spring和结合案例,另一个是和springboot结合的案例,这里需要知道一点,dubbo是依赖spring环境的,不可以单独使用。搭建dubbo案例,需要安装zookeeper,可以从网上下载一个,解压后运行zkServer.cmd即可,zookeeper默认端口2181
1、dubbo+spring 的方式搭建
1) 首先如果一个服务对其他服务公开接口,那么我们需要将这些对外的公共接口单独拿出来。第一步就是新建一个单独的公共接口模块
这里为了简单,只有一个用户接口
public interface UserService {
/**
* 获取用户名称
*/
String userName();
/**
* 获取用户ID
*/
String userId();
}
2)、新建一个dubbo集成spring的服务模块
dubbo的服务模块,这里以最简易的方式搭建,一个公共接口实现类,一个服务启动类,一个dubbo配置文件。
我们先看看pom需要引入的依赖,这里是父pom.xml
<?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>com.zl.dubbo</groupId>
<artifactId>dubbo_demo</artifactId>
<packaging>pom</packaging>
<version>1.0-SNAPSHOT</version>
<modules>
<module>api</module>
<module>client</module>
<module>service</module>
<module>bootServer</module>
<module>bootClient</module>
</modules>
<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>
<springframework.version>4.0.2.RELEASE</springframework.version>
<dubbo.version>2.5.7</dubbo.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-core</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-context</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>spring-webmvc</artifactId>
<version>${springframework.version}</version>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
<version>0.3</version>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.5</version>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<version>${dubbo.version}</version>
<scope>compile</scope>
<exclusions>
<exclusion>
<artifactId>spring</artifactId>
<groupId>org.springframework</groupId>
</exclusion>
</exclusions>
</dependency>
</dependencies>
</project>
当前服务模块的pom.xml:只需要引下父模块即可
<?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">
<parent>
<artifactId>dubbo_demo</artifactId>
<groupId>com.zl.dubbo</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service</artifactId>
<dependencies>
<dependency>
<groupId>com.zl.dubbo</groupId>
<artifactId>api</artifactId>
<version>1.0-SNAPSHOT</version>
<scope>compile</scope>
</dependency>
</dependencies>
</project>
UserService公共接口实现类: 注意:这里的@Service注解时dubbo提供的注解,不是spring的注解!
@Service
public class UserServiceImpl implements UserService {
@Override
public String userName() {
return "张三";
}
@Override
public String userId() {
return "10001";
}
}
dubbo集成spring配置文件: 这里的dubbo我们使用注解的方式 dubbo-annotation.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:context="http://www.springframework.org/schema/context"
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-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!--<context:component-scan base-package="com.zl"/>-->
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="storeServer_annotation"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.0.101:2181"/>
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="rmi" port="20880"/>
<dubbo:annotation package="com.zl.service" />
</beans>
以及最后一个启动类: Application.class
public class Application {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context =
new ClassPathXmlApplicationContext("classpath:dubbo-annotation.xml");
//开启
context.start();
System.out.println("启动成功……");
System.in.read(); //避免程序结束,这里需要阻塞
}
}
到此位置 ,dubbo服务端编写完毕
3)、编写客户端模块
客户端模块,这里主要作用是调用服务端接口,返回接口测试。为了简单java代码只有一个controller
这里是使用spring,所以我们为了测试需要集成tomcat,使用web.xml进行启动客户端服务进行测试。
首先需要新建客户端controller , @Reference是Dubbo提供的注解。这里的UserService是Dubbo通过zookeeper反射生成的一个代理对象,具体原理后面自行百度。
@Controller
public class UserController {
@Reference
private UserService userService;
@GetMapping("/index")
public String user(HttpServletRequest request){
String userId = userService.userId();
String userName = userService.userName();
request.setAttribute("userId",userId);
request.setAttribute("userName",userName);
return "index";
}
}
新建dubbo配置文件以及springMvc配置文件。 dubbo-annotation.xml ; spring-mvc.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:context="http://www.springframework.org/schema/context"
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-3.1.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="enjoyStore_annotation"/>
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry address="zookeeper://192.168.0.101:2181" check="false"/>
<dubbo:annotation package="com.zl.client.controller" />
</beans>
<?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:p="http://www.springframework.org/schema/p"
xmlns:context="http://www.springframework.org/schema/context"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans-3.1.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context-3.1.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc-4.0.xsd">
<context:component-scan base-package="com.zl.client.controller"></context:component-scan>
<mvc:annotation-driven/>
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver">
<property name="prefix" value="/"></property>
<property name="suffix" value=".jsp"></property>
</bean>
<import resource="dubbo_annotation.xml"/>
</beans>
后面是web.xml
<?xml version="1.0" encoding="UTF-8"?>
<web-app xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://java.sun.com/xml/ns/javaee"
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_3_0.xsd"
version="3.0">
<display-name>Archetype Created Web Application</display-name>
<!-- Spring MVC servlet -->
<servlet>
<servlet-name>SpringMVC</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring-mvc.xml</param-value>
</init-param>
<load-on-startup>1</load-on-startup>
<async-supported>true</async-supported>
</servlet>
<servlet-mapping>
<servlet-name>SpringMVC</servlet-name>
<!-- 此处可以可以配置成*.do,对应struts的后缀习惯 -->
<url-pattern>/</url-pattern>
</servlet-mapping>
<welcome-file-list>
<welcome-file>/index.jsp</welcome-file>
</welcome-file-list>
</web-app>
以及一个简单的jsp页面,显示用户名和名称
<%@ page language="java" contentType="text/html;charset=utf-8" pageEncoding="UTF-8"%>
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">
<html>
<body>
<h2>Hello World!666</h2>
<h2>用户ID: ${userId}</h2>
<h2>用户名: ${userName}</h2>
</body>
</html>
到此位置,客户端服务搭建完毕。好了,我们启动开始测试吧。
先启动服务端:即运行Application类的main方法。
然后为客户端client添加一个tomcat容器,启动。
访问: http://localhost:8080/index
发现数据获取完毕,我们在打个断点看看。
发现这个userService对象的确是一个代理对象。 结束!
2、使用dubbo+springboot搭建案例
搭建完spring的案例,springboot就更简单了。
1)、首先一样的道理,公共接口模块已经定义好了,这里不需要定义了。我们从服务端模块开始
application.yml配置 : 端口、dubbo.name随便设置
server:
port: 8090
dubbo:
name: serverBoot
zookeeper: zookeeper://192.168.0.101:2181
UserService实现类: UserServiceImpl.class
@Service
public class UserServiceImpl implements UserService{
@Override
public String userName() {
return "李四";
}
@Override
public String userId() {
return "10003";
}
}
springboot这里就用@Bean注解来进行配置了:DubboBean.class
@Configuration
public class DubboBean {
@Value("${dubbo.zookeeper}")
private String zkAddr;
@Value("${dubbo.name}")
private String appName;
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(appName);
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(zkAddr);
return registryConfig;
}
@Bean
public ProtocolConfig protocolConfig() {
ProtocolConfig protocolConfig = new ProtocolConfig();
protocolConfig.setName("dubbo");
protocolConfig.setPort(20881);
return protocolConfig;
}
}
最后一个启动类
@SpringBootApplication
@DubboComponentScan(basePackages = "com.zl.service")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
2)、客户端
application.yml配置:
server:
port: 8082
dubbo:
name: serverBoot
zookeeper: zookeeper://192.168.0.101:2181
UserController.class
@RestController
public class UserController {
@Reference
private UserService userService;
@GetMapping("/user")
public String user(){
String userId = userService.userId();
String userName = userService.userName();
return "用户ID: "+userId+", 用户名称:"+userName;
}
}
DubboInit.class 配置类
@Configuration
public class DubboInit {
@Value("${dubbo.zookeeper}")
private String zkAddr;
@Value("${dubbo.name}")
private String appName;
@Bean
public ApplicationConfig applicationConfig() {
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName(appName);
return applicationConfig;
}
@Bean
public RegistryConfig registryConfig() {
RegistryConfig registryConfig = new RegistryConfig();
registryConfig.setAddress(zkAddr);
return registryConfig;
}
}
最后一个启动类:
@SpringBootApplication
@DubboComponentScan("com.zl.client")
public class Application {
public static void main(String[] args) {
SpringApplication.run(Application.class,args);
}
}
大功告成,老套路,先启动服务模块,然后启动客户端模块
访问:http://localhost:8082/user
我们在打个断点卡看看:
到此位置,dubbo案例搭建+测试完毕,我们再来看看整个案例的总体模块划分
以上,有帮助的点个赞啊!