简介
首先要弄清楚dubbo是什么东西,看很多介绍说dubbo是一个分布式服务框架(RPC),其实准确的说dubbo不仅仅是分布式服务框架,它还包含了一些资源调度服务治理的工作。 dubbo中的几个重要角色:
Provider: 暴露服务的服务提供方。 Consumer: 调用远程服务的服务消费方。 Registry: 服务注册与发现的注册中心。 Monitor: 统计服务的调用次调和调用时间的监控中心。 Container: 服务运行容器。
Registry就是注册中心,注册中心只是作为服务的注册和发现,不转发调用。Provider在启动的时候就会把它能提供的服务都注册到Registry上。Consumer在启动的时候就会像Registry订阅它要消费的服务。如果一个服务有多个提供者就会根据负载均衡算法选择一个,默认的算法是随机算法。当服务变化的时候,Registry会向订阅了变化服务的Consumer。
简单例子
这里我们使用的注册中心是Zookeeper,Zookeeper的安装与配置可以参考Zookeeper初遇。在调试的过程中我们可能会使用到dubbo的admin,这个可以在网上下载一个安装了。最后自己在dubbo github下载下来自己打包。dubbo是使用maven来管理构建的,可以在父目录执行:
mvn package -Dmaven.skip.test=true
也可以在dubbo-admin这个目录下执行,只打包admin工程,打包完成之后在target目录下可以看到一个war包。
注意:执行mvn命令需要安装配置了maven
dubbo-admin是一个Java Web应用,需要Java容器,可以选择tomcat,把dubbo-admin的war包拷贝到tomcat的webapps目录下(可以修改名字,访问路径为war包的名字),然后启动服务器就可以了。
下面是我的访问页面链接,因为我配的tomcat的端口是7073:
dubbo-admin有2个默认的用户一个是root密码默认是root,另一个是guest,密码默认是guest,可以在web应用的根目录下的WEB-INF下的dubbo.properties中配置修改。
Provider
package cn.freemethod.dubbo.service
public interface DemoService {
String sayHello(String name);
}
package cn.freemethod.dubbo.service.impl;
import cn.freemethod.dubbo.service.DemoService;
public class DemoServiceImpl implements DemoService {
@Override
public String sayHello(String name) {
return "Hello " + name;
}
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
public class Provider {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"remote-provider.xml"});
context.start();
System.in.read(); // 按任意键退出
}
}
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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:property-placeholder location="remote-provider.properties" ignore-unresolvable="true"/>
<dubbo:application name="appNameProvider" owner="appOwnerName" organization="appOrganizationName"/>
<dubbo:registry id="registryId" protocol="zookeeper" address="127.0.0.1:2181" timeout="5000"/>
<dubbo:monitor protocol="registry"/>
<dubbo:protocol name="dubbo" port="25881" accesslog="/var/log/dubbo/access/freemethod.log"/>
<dubbo:service interface="cn.freemethod.dubbo.service.DemoService" ref="demoService" />
<bean id="demoService" class="cn.freemethod.dubbo.service.impl.DemoServiceImpl" />
</beans>
dubbo的基本配置:
<dubbo:application name="appNameProvider" owner="appOwnerName" organization="appOrganizationName"/>
<dubbo:registry file="/var/chace" protocol="zookeeper" address="127.0.0.1:2181" timeout="5000"/>
<dubbo:monitor protocol="registry"/>
<dubbo:protocol name="dubbo" port="25881" accesslog="/var/log/dubbo/access/freemethod.log"/>
application:配置可以在admin上显示应用基本信息,主要是出了问题能够找到对应的负责人。 registry:是配置注册中心,常用的就是使用Zookeeper协议了,address就是注册中心的链接。file是配置缓存,缓存的是:注册中心的列表,服务提供者列表
monitor:配置监控中心使用的协议。
protocol:配置远程调用使用的协议,一般常用的是dubbo,也可以使用rmi,thrift等。accesslog是配置访问日志文件。
上面的Provider其实就是普通的接口和实现,最关键的是上面的配置中的:
<dubbo:service interface="cn.freemethod.dubbo.service.DemoService" ref="demoService" />
这个就是dubbo暴露的接口服务。在Provider启动的时候,dubbo会把这个服务注册到注册中心上。
注意:上面的配置为了更加了直观,所以没有使用占位符,remote-provider.properties文件的内容可以参考附录A
Consumer
package cn.freemethod.dubbo.service;
public interface DemoService {
String sayHello(String name);
}
import org.springframework.context.support.ClassPathXmlApplicationContext;
import cn.freemethod.dubbo.service.DemoService;
public class Consumer {
public static void main(String[] args) throws Exception {
@SuppressWarnings("resource")
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(new String[] {"remote-consumer.xml"});
context.start();
DemoService demoService = (DemoService)context.getBean("demoService"); // 获取远程服务代理
String hello = demoService.sayHello("world"); // 执行远程方法
System.out.println( hello ); // 显示调用结果
}
}
<?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"
xmlns:context="http://www.springframework.org/schema/context"
xsi:schemaLocation="http://www.springframework.org/schema/beans
http://www.springframework.org/schema/beans/spring-beans.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:property-placeholder location="remote-consumer.properties" ignore-unresolvable="true"/>
<dubbo:application name="appNameConsumer" owner="appOwnerName" organization="appOrganizationName"/>
<dubbo:registry id="registryId" protocol="zookeeper" address="127.0.0.1:2181" timeout="5000"/>
<dubbo:monitor protocol="registry"/>
<dubbo:protocol name="dubbo" port="25881" accesslog="/var/log/dubbo/access/freemethod.log"/>
<dubbo:reference id="demoService" interface="cn.freemethod.dubbo.service.DemoService" />
</beans>
上面的Consumer和Provider一样都是简单的接口,Consumer一样远程服务的配置是:
<dubbo:reference id="demoService" interface="cn.freemethod.dubbo.service.DemoService" />
注意:这里的配置id可以和Provider的id不同但是interface必须相同,这个接口可以引用相同的接口,也可以是2个同名的接口
对于上面的Provider和Consumer可以放在一个工程中,但是最后放在2个工程中,对于接口可以单独一个工厂,Provider和Consumer都依赖这个接口工程。
dubbo的负载均衡算法
dubbo的负载均衡主要是在有多个服务提供者的时候,服务消费者怎样选择的算法,不同算法各有优缺点。
-
Random LoadBalance 随机,按权重设置随机概率。 在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。
-
RoundRobin LoadBalance 轮循,按公约后的权重设置轮循比率。 存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。
-
LeastActive LoadBalance 最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。 使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。
-
ConsistentHash LoadBalance 一致性Hash,相同参数的请求总是发到同一提供者。当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。缺省只对第一个参数Hash。如果要修改,可以配置:
<dubbo:parameter key="hash.arguments" value="0,1" />
缺省用160份虚拟节点,如果要修改,可以配置:
<dubbo:parameter key="hash.nodes" value="320" />
附录A
#这个主要用于配置注册中心缓存,缓存注册中心列表和服务提供在列表
cache.path=/usr/home/cache
app.owner.name = freemethod
app.organization.name = freemethod
app.name = freemethod
service.protocol = dubbo
service.port = 25881
service.log = /var/log/dubbo/access/freemethod.log
#registry.address=192.168.0.224:2181,192.168.0.225:2181,192.168.0.226:2181
registry.address=127.0.0.1:2181
registry.protocol=zookeeper
connect.service.max.thread.threads.size =20