目录
1.简介
2.架构
3.配置监控中心
4.模拟服务提供者
5.模拟服务消费者
6.消费者的其他配置
6.1协议
6.2启动时检查
6.3超时和重试
6.4负载均衡
7.补充
1.简介
Apache Dubbo是一款高性能的Java RPC框架。其前身是阿里巴巴公司开源的一个高性能、轻量级的开源Java RPC框架,可以和Spring框架无缝集成。
RPC
RPC全称为remote procedure call,即远程过程调用。比如两台服务器A和B,A服务器上部署一个应用,B服务器上部署一个应用,A服务器上的应用想调用B服务器上的应用提供的方法,由于两个应用不在一个内存空间,不能直接调用,所以需要通过网络来表达调用的语义和传达调用的数据。
RPC是一个泛化的概念,RPC并不是一个具体的技术,而是指整个网络远程调用过程。严格来说一切远程过程调用手段都属于RPC范畴。各种开发语言都有自己的RPC框架。Java中的RPC框架比较多,广泛使用的有RMI、Hessian、Dubbo等。
2.架构
Dubbo架构图(Dubbo官方提供)如下:
0.tomcat容器启动。
1.将提供者服务注册到注册中心当中,dubbo提供的注册中心就是zookeeper。
2.消费者想要调用提供者提供的方法时,从注册中心拉去提供者的服务地址。
3.若提供者的服务地址发生了改变,注册中心则会马上通知消费者。
4.消费者根据服务中心提供的服务地址就可以直接调用提供者了,并且在调用提供者服务之后,就会将提供者的地址主动缓存下来。
5.监控消费者调用提供者的次数。
消费者调用后会将提供者提供的路径缓存下来,这样即使注册中心宕机,消费者也还是可以通过缓存的地址调用提供者。
zookeeper使用的连接方式是长链接。
3.配置监控中心
在开发时,需要知道Zookeeper注册中心都注册了哪些服务,有哪些消费者来消费这些服务。我们可以通过部署一个管理中心来实现。其实管理中心就是一个web应用,部署到tomcat即可。
步骤:
1.GitHub上下一个dubbo-admin的war包。
2.准备一个tomcat容器,将war包放在tomcat的webapps下,并修改tomcat端口号,避免端口冲突。
3.启动tomcat,在启动完成后会将dubbo-admin.war解压,此时进入到WEB-INF中修改dubbo.properties,将其中连接zookeeper的配置进行修改。
4.重启tomcat。
5.浏览器访问http://localhost:自己定义的端口号/dubbo-admin/即可。
访问时输入用户名密码,都是root。即可出现如下页面。
由于目前没有启动任何的服务提供者、消费者的项目,所以没有什么看的。
4.模拟服务提供者
创建服务提供者接口
public interface HelloService {
public String sayHello(String name);
}
创建服务提供者实现类
@Service //把此服务注册到zookeeper dubbo的注解
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}
创建配置文件
<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
xmlns:mvc="http://www.springframework.org/schema/mvc"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.xsd
http://www.springframework.org/schema/mvc
http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://code.alibabatech.com/schema/dubbo
http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context
http://www.springframework.org/schema/context/spring-context.xsd">
<!-- 当前应用名称,用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
<dubbo:application name="dubbodemo_provider" />
<!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 注册 消费者调用当前项目时提供的协议名称和端口号 协议名称使用dubbo的协议 端口默认是20880 -->
<dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>
<!-- 扫描指定包,加入@Service注解的类会被发布为服务 -->
<dubbo:annotation package="com.study.service.impl" />
</beans>
创建main方法加载配置文件
public static void main(String[] args) {
ClassPathXmlApplicationContext app = new ClassPathXmlApplicationContext("classpath:applicationContext-provider.xml");
app.start();
while (true){
}
}
效果:
在监控中心中看到了已经启动的服务提供者。
还有此服务提供的方法。
或者使用tomcat启动,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_2_5.xsd"
version="2.5">
<!-- 监听器监听其他的spring配置文件 -->
<context-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:applicationContext-provider.xml</param-value>
</context-param>
<listener>
<listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
</listener>
</web-app>
5.模拟服务消费者
创建controller
@Controller
@RequestMapping("/demo")
public class HelloController {
@Reference //dubbo的远程注入方式
private HelloService helloService;
@RequestMapping("/hello")
@ResponseBody
public String getName(String name){
//远程调用
String result = helloService.sayHello(name);
System.out.println(result);
return result;
}
}
创建service
//包名要和提供者的包名保持一致
public interface HelloService {
public String sayHello(String name);
}
创建springmvc的配置文件
用于配置包扫描以及dubbo的配置
<?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:aop="http://www.springframework.org/schema/aop"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
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.xsd
http://www.springframework.org/schema/mvc http://www.springframework.org/schema/mvc/spring-mvc.xsd
http://www.springframework.org/schema/aop http://www.springframework.org/schema/aop/spring-aop.xsd
http://code.alibabatech.com/schema/dubbo http://code.alibabatech.com/schema/dubbo/dubbo.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context.xsd">
<context:component-scan base-package="com.study"/>
<!--告诉zookeeper 当前项目是哪个-->
<dubbo:application name="dubbodemo_consumer"/>
<!--链接注册中心-->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!--注解扫描 扫描的是dubbo的 @Reference注解-->
<dubbo:annotation package="com.itheima"/>
<!-- timeout:每次请求都会等待3秒 retries失败后重试次数-->
<dubbo:consumer timeout="3000" retries="0"/>
</beans>
创建web.xml配置文件
用于加载springmvc的配置文件,以及前端控制器
<?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_2_5.xsd"
version="2.5">
<servlet>
<servlet-name>springmvc</servlet-name>
<servlet-class>org.springframework.web.servlet.DispatcherServlet</servlet-class>
<!-- 指定加载的配置文件 ,通过参数contextConfigLocation加载-->
<init-param>
<param-name>contextConfigLocation</param-name>
<param-value>classpath:spring/spring-mvc.xml</param-value>
</init-param>
</servlet>
<servlet-mapping>
<servlet-name>springmvc</servlet-name>
<url-pattern>*.do</url-pattern>
</servlet-mapping>
</web-app>
配置tomcat后启动
启动消费者后发现监控中心中还是没有消费者服务.
我们调用一次消费者的方法:
发现有所响应.并且在监控中心出现了消费者的服务.
此时我们把提供者服务关闭,就只剩下了消费者服务
并且告诉我们此服务没有提供者.
6.消费者的其他配置
6.1协议
<dubbo:protocol name="dubbo" port="20880"/>
一般在服务提供者一方配置,可以指定使用的协议名称和端口号。 其中Dubbo支持的协议有:dubbo、rmi、hessian、http、webservice、rest、redis等。 推荐使用的是dubbo协议。 dubbo 协议采用单一长连接和 NIO 异步通讯,适合于小数据量大并发的服务调用,以及服务消费者机器数远大于服务提供者机器数的情况。不适合传送大数据量的服务,比如传文件,传视频等,除非请求量很低。 也可以在同一个工程中配置多个协议,不同服务可以使用不同的协议,例如:
<!-- 多协议配置 -->
<dubbo:protocol name="dubbo" port="20880" />
<dubbo:protocol name="rmi" port="1099" />
<!-- 使用dubbo协议暴露服务 -->
<dubbo:service interface="com.study.api.HelloService" ref="helloService" protocol="dubbo" />
<!-- 使用rmi协议暴露服务 -->
<dubbo:service interface="com.study.api.DemoService" ref="demoService" protocol="rmi" />
6.2启动时检查
<dubbo:consumer check="true"/>
上面这个配置需要配置在服务消费者一方,如果不配置默认check值为true。Dubbo 缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止 Spring 初始化完成,以便上线时,能及早发现问题。可以通过将check值改为false来关闭检查。 建议在开发阶段将check值设置为false,在生产环境下改为true。
6.3超时和重试
<!--设置超时时间以及重试次数-->
<dubbo:consumer timeout="3000" retries="0"/>
如果不做如上配置,默认提供者1秒之内没有响应结果就重试,总共会重试3次
6.4负载均衡
负载均衡(Load Balance):其实就是将请求分摊到多个操作单元上进行执行,从而共同完成工作任务。在集群负载均衡时,Dubbo 提供了多种均衡策略(包括随机(random)、轮询(roundRobin)、最少活跃调用数(leastActive)、一致性Hash(consistentHash)),默认为random随机调用。配置负载均衡策略,既可以在服务提供者一方配置,也可以在服务消费者一方配置,如下:
@Controller
@RequestMapping("/demo")
public class HelloController {
//在服务消费者一方配置负载均衡策略
@Reference(check = false,loadbalance = "random")
private HelloService helloService;
@RequestMapping("/hello")
@ResponseBody
public String getName(String name){
//远程调用
String result = helloService.sayHello(name);
System.out.println(result);
return result;
}
}
//在服务提供者一方配置负载均衡
@Service(interfaceClass = HelloService.class,loadbalance = "random")
public class HelloServiceImpl implements HelloService {
public String sayHello(String name) {
return "hello " + name;
}
}
7.补充
1.以上代码的服务者和消费者的service是固定写在包里,那也就意味着如果有所修改就需要在服务端和消费端都进行修改,产生了代码的冗余。我们如果是maven项目可以将service的代码抽取到一个maven工程,需要依赖此接口的工程只需要在自己工程的pom.xml文件中引入maven坐标即可。
2.Dubbo底层是基于代理技术为HelloService接口创建代理对象,远程调用是通过此代理对象完成的。可以通过开发工具的debug功能查看此代理对象的内部结构。另外,Dubbo实现网络传输底层是基于Netty框架完成的。
3.在远程调用的过程中,如果涉及到了java对象,需要进行序列化,因此java对象需要实现序列化接口。