dubbo
dubbo背景
在如今设备配置已经到达极限的时候,则需要进行分布式进行处理,将一些应用功能分开管理,但是又必须得互相有沟通,可以通过简单的接口暴露和RPC引用远程服务,通过配置URL地址进行调用,通过F5等硬件进行负载均衡.但是当应用服务规模再进一步扩大的情况下,如果只是简单的通过RMI等方法暴露接口的话,服务的URL配置和管理将变得特别的困难,这个时候就需要实现一个注册中心,动态地注册和发现服务,使得服务的位置透明,并通过在消费方获取服务提供地址列表,实现软负载均衡
但是如果在进一步发展,服务器的依赖关系变得错综复杂,甚至分不清那个服务在那个服务之前启动,这个时候需要自动画出应用间的依赖图,来帮助架构师理清系统关系.
但是当应用规模扩大的时候还必须要确定多少台机器合适,也必须要有一个服务来进行调用统计,响应时间计算,通过这些来判断需要多少机器,来进行管理.
dubbo架构
这就是dubbo基本的架构图.
大致流程:
- 服务提供方应该向注册中心注册自己要发布的服务,
- 其次消费方去注册中心订阅自己所需要的服务
- 当注册中心发现有服务的话会通知消费方服务提供放暴露的接口地址,如果一个服务有多个提供者,则会返回一个服务接口列表,由消费方调用
- 消费方依靠这个地址列表去找到对应的服务提供者.这里如果有多台机器在代码中会可以实现软负载均衡,寻找合适的服务提供者去请求.
- 服务方和消费方也都会在内存中存储调用次数和时间,定时向监控中心发送数据.
API方式
API方式也是根据上述的流程.
首先必须得有一个注册中心: 一般来说注册中心使用zookeeper,zookeeper启动过程可以去网上搜索.挺简单的.
接着应该有一个服务提供者提供服务.
使用Dubbo的服务必须有几个参数得指明.一个是application,也就是提供服务的应用.一个是注册中心的配置,因为你要向注册中心注册一个服务.这也是必须的.来看一下提供方代码:
首先应该有一个接口,也就是提供的服务的接口:
public interface Calculator {
int add(int x,int y);
}
// 实现类:
public class CalculatorImpl implements Calculator {
@Override
public int add(int x, int y) {
return x+y;
}
}
接着就可以提供服务了:
public static void main(String[] args) throws IOException {
// 这个也就是提供服务的类,当有消费方请求的时候使用这个类来进行计算并且返回.
Calculator calculator = new CalculatorImpl();
// 需要有一个应用来发布这个服务.服务必须得有名字
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("add");
// 连接注册服务配置
RegistryConfig registryConfig = new RegistryConfig();
// 配置本地的zookeeper注册中心.还可以使用广播的方式,只需要将zookeeper改为broadcast即可
registryConfig.setAddress("zookeeper://192.168.1.202:2181");
registryConfig.setUsername("superj88");
registryConfig.setPassword("superj88");
// 服务提供协议配置 为服务提供协议配置.这里设置为dubbo,当然了,也可以是rest也就是http协议.
// RPC只是一个框架,具体实现怎么都可以,当然了,必须得经过网络传输
ProtocolConfig protocol = new ProtocolConfig();
protocol.setName("dubbo");
// 设置监听的端口
protocol.setPort(12345);
protocol.setThreads(200);
// 服务提供者暴露服务配置
ServiceConfig service = new ServiceConfig();
// 设置服务暴露的应用
service.setApplication(applicationConfig);
service.setRegistry(registryConfig);// 多个注册中心用setRegistries()
// 设置协议
service.setProtocol(protocol);
// 设置接口,通过这个接口调用此服务
service.setInterface(Calculator.class);
service.setRef(calculator);
service.setVersion("1.0.0");
// 这里执行暴露服务操作,具体就是向注册中心注册自己的服务
service.export();
System.in.read();
}
消费方代码:
public static void main(String[] args) {
// 当前应用配置
ApplicationConfig applicationConfig = new ApplicationConfig();
applicationConfig.setName("consumer");
// 连接注册中心配置
RegistryConfig registry = new RegistryConfig();
registry.setAddress("zookeeper://localhost:2181");
registry.setUsername("superj88");
registry.setPassword("superj88");
applicationConfig.setRegistry(registry);
// 引用远程服务
ReferenceConfig<Calculator> reference = new ReferenceConfig<>(); // 此实例很重,封装了与注册中心的连接以及与提供者的连接,请自行缓存,否则可能造成内存和连接泄漏
reference.setApplication(applicationConfig);
reference.setRegistry(registry); // 多个注册中心可以用setRegistries()
reference.setInterface(Calculator.class);
reference.setVersion("1.0.0");
// 这里消费方还必须得有要调用服务的接口.
Calculator calculator = reference.get();
System.out.println(calculator.add(100,2000));
}
Spring集成 xml方式
provider.xml配置:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- dubbo 应用名称 -->
<dubbo:application name="demo-provider"/>
<!-- 注册中心地址, 发布出来的服务要注册到这个地址上 -->
<dubbo:registry address="zookeeper://127.0.0.1:2181"/>
<!-- 使用的协议,这里是dubbo,绑定20890端口, 还有rest就是基于http协议的调用 -->
<dubbo:protocol name="dubbo" port="20890"/>
<!-- 指定发布的哪一个的服务 -->
<bean id="demoService" class="org.apache.dubbo.samples.basic.impl.DemoServiceImpl"/>
<!-- 这个是发布服务锁制定的接口 -->
<dubbo:service interface="org.apache.dubbo.samples.basic.api.DemoService" ref="demoService"/>
</beans>
consumer.xml配置:
<beans xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://dubbo.apache.org/schema/dubbo"
xmlns="http://www.springframework.org/schema/beans"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://dubbo.apache.org/schema/dubbo http://dubbo.apache.org/schema/dubbo/dubbo.xsd">
<!-- 消费者的应用名称 -->
<dubbo:application name="demo-consumer"/>
<!-- 注册中心 -->
<dubbo:registry group="aaa" address="zookeeper://127.0.0.1:2181"/>
<!-- 表示自己要使用那个服务 -->
<dubbo:reference id="demoService" check="false" interface="org.apache.dubbo.samples.basic.api.DemoService"/>
</beans>
还有很多配置,详情请看dubbo官网http://dubbo.apache.org/zh-cn/docs/user/configuration/xml.html.
基于注解的配置:
provider
首先也必须要配置应用共享的一些属性,比如应用名称,注册地址,使用的协议和绑定的端口等.
dubbo.application.name=annotation-provider
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.protocol.name=dubbo
dubbo.protocol.port=20880
指定包的扫描路径:
@EnableDubbo(scanBasePackages = "org.apache.dubbo.samples.simple.annotation.impl")
@PropertySource("classpath:/spring/dubbo-provider.properties")
static public class ProviderConfiguration {
}
使用Service注解暴露服务
@Service(protocol = {"dubbo","rest"},version = "1.0", timeout=3000)
// 这里的@Path路径中,如果上面协议中指定了rest服务,必须要指明路径.不然会报错.
@Path("moocOne")
public class DubboTestService implements IDubboTestService {
// 具体实现
}
consumer
配置应用基本属性:
dubbo.application.name=annotation-consumer
dubbo.registry.address=zookeeper://127.0.0.1:2181
dubbo.consumer.timeout=3000
消费方使用服务
@Component("annotationAction")
public class AnnotationAction {
// 通过此注解引用服务
@Reference
private AnnotationService annotationService;
public String doSayHello(String name) {
return annotationService.sayHello(name);
}
}
指定spring扫描路径
@Configuration
@EnableDubbo(scanBasePackages = "org.apache.dubbo.samples.simple.annotation.action")
@PropertySource("classpath:/spring/dubbo-consumer.properties")
@ComponentScan(value = {"org.apache.dubbo.samples.simple.annotation.action"})
static public class ConsumerConfiguration {
}