Dubbo简介
互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的。现在核心业务抽取出来,作为独立的服务。
1、用途
2、架构
节点介绍
1、Provider:服务提供方
2、Register:服务的注册和订阅的注册中心
3、Consumer:服务的消费者
4、Monitor:监控中心,用于统计服务的调用次调和调用时间。(可以没有)
5、Container:服务运行容器。
服务调用过程
服务运行容器加载启动服务提供者-->服务者在注册中心注册自己要对外提供的服务-->消费者向注册中心订阅需要的服务-->注册中心通知消费者提供者地址列表-->消费者基于软负载均衡,选择一台提供者进行调用。若调用失败,换另一台再次调用。--> 监控中心统计在内存中累计调用次数和调用时间。
架构好处
1、注册中心不转发请求,压力较小。服务提供者和消费者只在启动时与注册中心交互
2、监控中心统计在内存中累计调用次数和调用时间。
3、注册中心使用集群,出现宕机可以即时切换。注册中心数据库宕机不影响服务的订阅,只是不能进行注册
4、可以有多个服务提供方提供服务。
2、Dubbo与Zookeeper配合使用
1、linux安装zookeeper
Zookeeper一个分布式的服务框架,能做到集群管理数据 ,这里能很好的作为Dubbo服务的注册中心
clientPort:监听客户端连接的端口。
tickTime:基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime。
maxClientCnxns:限制连接到 ZooKeeper 的客户端的数量等
dataDir和dataLogDir:分别用于snapshot和事务日志的输出
2、安装dubbo-admin管理页面
注:dubbo.properties默认提供了两组账号密码:root admin;guest guest。
3、Dubbo的简单实现
1、创建服务提供方:
结构如下:
provider代码:
DemoService和DemoServiceImpl定义了两个对外提供的方法
package com.alibaba.dubbo.demo.impl;
import com.alibaba.dubbo.demo.Persion;
import java.util.List;
/**
* Created by yi on 2018/2/28.
*/
public interface DemoService {
List getPermissions(Long id);
List getPersion(String name, String addr, Integer age, String gender);
}
package com.alibaba.dubbo.demo.impl;
import com.alibaba.dubbo.demo.Persion;
import java.util.ArrayList;
import java.util.List;
public class DemoServiceImpl implements DemoService {
public List getPermissions(Long id) {
List demo = new ArrayList();
demo.add(String.format("Permission_%d", id - 1));
demo.add(String.format("Permission_%d", id));
demo.add(String.format("Permission_%d", id + 1));
return demo;
}
@Override
public List getPersion(String name, String address, Integer age, String gender) {
List persions = new ArrayList<>();
Persion persion = null;
for (int i = 0; i < 10; i++) {
persion = new Persion();
persion.setName(name + i);
persion.setAddr(address + i);
persion.setAge(age + i);
persion.setGender(gender+i);
persions.add(persion);
}
return persions;
}
}
persion对象
package com.alibaba.dubbo.demo;
/**
* Created by yi on 2018/2/24.
*/
public class Persion {
private String name;
private String addr;
private Integer age;
private String gender;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddr() {
return addr;
}
public void setAddr(String addr) {
this.addr = addr;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
public String getGender() {
return gender;
}
public void setGender(String gender) {
this.gender = gender;
}
}
Provider:注册服务并持续提供服务
package com.alibaba.dubbo.demo.impl;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;
public class Provider {
public static void main(String[] args) throws IOException {
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
System.out.println(context.getDisplayName() + ": here");
context.start();
System.out.println("服务已经启动...");
System.in.read();
}
}
消费方代码:使用GenericService实现泛型接收返回值。使用java代码配置zookeeper。
package com.alibaba.dubbo.consumer;
import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;
public class Consumer {
//缓存持续时间
private static Long cacheDubTimes = 1000 * 60 *12L;
//应用信息(提供方名称)
private static ApplicationConfig APPLICATION = null;
//zookeeper 注册中心url
private static RegistryConfig REGISTRY = null;
//dubbo实体类
private static DubConfig dubConfig = null;
private static ConsumerConfig CONSUMER = null;
//缓存保存(接口名称,泛型service)
private static Cache servicesCache= CacheBuilder.newBuilder().expireAfterAccess(
cacheDubTimes, TimeUnit.SECONDS).maximumSize(200).build();
/**
*
* @param interfaceName 接口名称
* @return
*/
private static ReferenceConfig createReferenceConfig(String interfaceName) {
//接口引用
ReferenceConfig referenceConfig = new ReferenceConfig<>();
referenceConfig.setApplication(getApplicationConfig());
referenceConfig.setRegistry(getRegistryConfig());
referenceConfig.setConsumer(getConsumerConfig());
referenceConfig.setInterface(interfaceName);
referenceConfig.setGeneric(true);
return referenceConfig;
}
private static ApplicationConfig getApplicationConfig() {
if (APPLICATION != null) {
return APPLICATION;
}
APPLICATION = new ApplicationConfig(dubConfig.getDubApplicationName());
return APPLICATION;
}
private static RegistryConfig getRegistryConfig(){
if (REGISTRY != null) {
return REGISTRY;
}
REGISTRY = new RegistryConfig(String.join("", "zookeeper://", dubConfig.getDubZookeeperUrl()));
return REGISTRY;
}
private static ConsumerConfig getConsumerConfig(){
if (CONSUMER != null) {
return CONSUMER;
}
CONSUMER = new ConsumerConfig();
CONSUMER.setTimeout(dubConfig.getDubTimeout());
CONSUMER.setRetries(0);
return CONSUMER;
}
private static GenericService getServiceByCache(String interfaceName) {
StringBuilder serviceKey = new StringBuilder(String.join("", interfaceName));
GenericService service = null;
try {
service = servicesCache.get(serviceKey.toString(), new Callable() {
@Override
public GenericService call() throws Exception {
ReferenceConfig referenceConfig = createReferenceConfig(interfaceName);
GenericService genericService = referenceConfig.get();
servicesCache.put(serviceKey.toString(), genericService);
return genericService;
}
});
} catch (java.util.concurrent.ExecutionException e) {
e.printStackTrace();
}
if (service != null) {
return service;
}
servicesCache.put(serviceKey.toString(), null);
return service;
}
public static void main(String[] args) {
if (dubConfig == null) {
dubConfig = new DubConfig();
dubConfig.setDubTimeout(3000);
dubConfig.setDubApplicationName("demotest-consumer");
dubConfig.setDubZookeeperUrl("192.168.60.131:2181");
}
GenericService genericService = getServiceByCache("com.alibaba.dubbo.demo.impl.DemoService");
String[] parameterTypes = new String[]{String.class.getName(), String.class.getName(), Integer.class.getName(), String.class.getName()};
Object[] dubArgs = new Object[]{"小明", "北京", "11", "男"};
Object obj= genericService.
$invoke("getPersion", parameterTypes, dubArgs);
System.out.println("--------- ---------- ------------ ---------");
System.out.println(obj);
}
}
部分内容引用: