一、dubbo的简介
二、dubbo的使用
1)dubbo需要的jar包
<dependency>
<groupId>org.jboss.netty</groupId>
<artifactId>netty</artifactId>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>dubbo</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework</groupId>
<artifactId>spring</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
</dependency>
2)注册中心
- zookeeper,推荐集群中部署奇数个节点,由于zookeeper挂掉一半的机器集群就不可用,所以部署4台和3台的集群都是在挂掉2台后集群不可用
- redis
- multicast,广播受到网络结构的影响,一般本地不想搭注册中心的话使用这种调用
- dubbo简易注册中心
三、dubbo的服务端
说明:其中dubbo的配置其中主要是在spring的配置文件中配置,或者单独的配置,配置之后在spirng的文件中应用。
1)创建dubbo的配置文件dubbo-provider.xml,在配置应用名
每个<dubbo:xxx />配置项都对应一个spring实例
<dubbo:application name="test"/>
2) 在spirng的文件中引用dubbo的配置文件
<import resource="spring-mybatis.xml" />
3)配置dubbo注解识别处理器,不指定包名的话会在spring bean中查找对应实例的类配置了dubbo注解的
<dubbo:annotation/>
4)配置注册中心,通过group指定注册中心分组,可通过register配置是否注册到该注册中心以及subscribe配置是否从该注册中心订阅
<dubbo:registry address="zookeeper://127.0.0.1:2181/" group="test"/>
5)配置服务协议,多网卡可通过IP指定绑定的IP地址,不指定或者指定非法IP的情况下会绑定在0.0.0.0,使用Dubbo协议的服务会在初始化时建立长连接
<dubbo:protocol name="dubbo" port="20880" accesslog="d:/access.log"></dubbo:protocol>
6)通过xml配置文件配置服务暴露,首先要有个spring bean实例(无论是注解配置的还是配置文件配置的),在下面ref中指定bean实例ID,作为服务实现类
<dubbo:service interface="com.web.foo.service.FirstDubboService" ref="firstDubboServiceImpl" version="1.0"></dubbo:service>
7)通过注解方式配置服务暴露,Component是Spring bean注解,Service是dubbo的注解(不要和spring bean的service注解弄混),如前文所述,dubbo注解只会在spring bean中被识别
@Component
@Service(version="1.0")
public class FirstDubboServiceImpl implements FirstDubboService{
@Override
public void sayHello(TestDto test){
System.out.println("Hello World!");
}
}
四、dubbo的消费者
同服务端配置应用名、注解识别处理器和注册中心。
配置客户端reference bean。客户端跟服务端不同的是客户端这边没有实际的实现类的,所以配置的dubbo:reference实际会生成一个spring bean实例,作为代理处理Dubbo请求,然后其他要调用处直接使用spring bean的方式使用这个实例即可。
xml配置文件配置方式,id即为spring bean的id,之后无论是在spring配置中使用ref="firstDubboService"还是通过@Autowired注解都OK
<dubbo:reference interface="com.web.foo.service.FirstDubboService"
version="1.0" id="firstDubboService" ></dubbo:reference>
另外开发、测试环境可通过指定Url方式绕过注册中心直连指定的服务地址,避免注册中心中服务过多,启动建立连接时间过长,如
<dubbo:reference interface="com.web.foo.service.FirstDubboService"
version="1.0" id="firstDubboService" url="dubbo://127.0.0.1:20880/"></dubbo:reference>
注解配置方式引用,
@Component
public class Consumer
{
@Reference(version="1.0")
private FirstDubboService service;
public void test()
{
TestDto test = new TestDto();
test.setList(Arrays.asList(new String[]{"a", "b"}));
test.setTest("t");
service.sayHello(test);
}
}
Reference被识别的条件是spring bean实例对应的当前类中的field,如上是直接修饰spring bean当前类中的属性
这个地方看了下源码,本应该支持当前类和父类中的public set方法,但是看起来是个BUG,Dubbo处理reference处部分源码如下
Method[] methods = bean.getClass().getMethods();
for (Method method : methods) {
String name = method.getName();
if (name.length() > 3 && name.startsWith("set")
&& method.getParameterTypes().length == 1
&& Modifier.isPublic(method.getModifiers())
&& ! Modifier.isStatic(method.getModifiers())) {
try {
Reference reference = method.getAnnotation(Reference.class);
if (reference != null) {
Object value = refer(reference, method.getParameterTypes()[0]);
if (value != null) {
method.invoke(bean, new Object[] { });//??这里不是应该把value作为参数调用么,而且为什么上面if条件判断参数为1这里不传参数
}
}
} catch (Throwable e) {
logger.error("Failed to init remote service reference at method " + name + " in class " + bean.getClass().getName() + ", cause: " + e.getMessage(), e);
}
}
}
三、dubb的监控中心
如果使用Dubbo自带的监控中心,可通过简单配置即可,先通过github获得dubbo-monitor的源码,部署启动后在应用配置如下
<dubbo:monitor protocol="registry" /> <!--通过注册中心获取monitor地址后建立连接-->
<dubbo:monitor address="dubbo://127.0.0.1:7070/com.alibaba.dubbo.monitor.MonitorService" /> <!--绕过注册中心直
四、服务路由
最重要辅助功能之一,可随时配置路由规则调整客户端调用策略,目前dubbo-admin中已提供基本路由规则的配置UI,到github下载源码部署后很容易找到地方,这里简单介绍下怎么用路由。
下面是dubbo-admin的新建路由界面,可配置信息都在图片中有,
比如现在我们有10.0.0.1~3三台消费者和10.0.0.4~6三台服务提供者,想让1和2调用4,3调用5和6的话,则可以配置两个规则,
1.消费者IP:10.0.0.1,10.0.0.2 ;提供者IP:10.0.0.4
2.消费者IP:10.0.0.3;提供者IP:10.0.0.5,10.0.0.6
另外,IP地址支持结尾为*匹配所有,如10.0.0.*或者10.0.*等。
不匹配的配置规则和匹配的配置规则是一致的。
配置完成后可在消费者标签页查看路由结果
五、负载均衡
dubbo提供4种负载均衡方式:
- Random,随机,按权重配置随机概率,调用量越大分布越均匀,默认是这种方式
- RoundRobin,轮询,按权重设置轮询比例,如果存在比较慢的机器容易在这台机器的请求阻塞较多
- LeastActive,最少活跃调用数,不支持权重,只能根据自动识别的活跃数分配,不能灵活调配
- ConsistentHash,一致性hash,对相同参数的请求路由到一个服务提供者上,如果有类似灰度发布需求可采用
dubbo的负载均衡机制是在客户端调用时通过内存中的服务方信息及配置的负责均衡策略选择,如果对自己系统没有一个全面认知,建议先采用random方式。
六、dubbo的过滤
有需要自己实现dubbo过滤器的,可关注如下步骤:
- dubbo初始化过程加载META-INF/dubbo/internal/,META-INF/dubbo/,META-INF/services/三个路径(classloaderresource)下面的com.alibaba.dubbo.rpc.Filter文件
-
文件配置每行Name=FullClassName,必须是实现Filter接口
-
@Activate标注扩展能被自动激活
-
@Activate如果group(provider|consumer)匹配才被加载
-
@Activate的value字段标明过滤条件,不写则所有条件下都会被加载,写了则只有dubbo URL中包含该参数名且参数值不为空才被加载
如下是dubbo rpc access log的过滤器,仅对服务提供方有效,且参数中需要带accesslog,也就是配置protocol或者serivce时配置的accesslog="d:/rpc_access.log"
@Activate(group = Constants.PROVIDER, value = Constants.ACCESS_LOG_KEY)
public class AccessLogFilter implements Filter {
}
七、结果缓存,省得自己再去写一个缓存,对缓存没有特殊要求的话直接使用dubbo的好了
八、分组合并,对RPC接口不同的实现方式分别调用然后合并结果的一种调用模式,比如我们要查用户是否合法,一种我们要查是否在黑名单,同时我们还要关注登录信息是否异常,然后合并结果