分布式服务框架--Dubbo
Dubbo 框架
一、Dubbo 框架介绍
1. Dubbo框架是什么?
Dubbo框架是一个分布式服务框架,致力于提供高性能和透明化的RPC远程服务调用方案,是阿里巴巴SOA 服务化治理方案的核心框架。
第一:分布式是指不同的多台服务器上面部署不同的服务模块,他们之间通过 RPC / Rmi 之间通信和调用,对外提供服务和组内协作
第二:RPC——remote Procedure Call Protocol– 远程过程调用协议。通过网络从远程计算机程序上请求服务,而不需要了解底层网络技术的协议。比如 A服务想要调用B服务上提供的方法,由于不在一个内存空间,不能直接调用,则需要通过网络来表达调用的语义和传达调用的数据.这里 user 就是 client 端,当 user 想发起一个远程调用时,它实际是通过本地调用 user-stub。user-stub 负责将调用的接口、方法和参数通过约定的协议规范进行编码并通过本地的 RPCRuntime 实例传输到远端的实例。远端 RPCRuntime 实例收到请求后交给 server-stub 进行解码后发起本地端调用,调用结果再返回给 user 端。是SOA 的一种实现 .SOA是一种面向服务的体系架构,它将应用程序的不同功能单元(称为服务)通过这些服务之间定义良好的接口和契约联系起来
-
1. client端的线程模型是什么样的?
传统的io client是请求应答模式,发送请求-->等待远程应答。dubbo底层是异步IO的,所有请求复用单一长连接,所以调用都不会阻在IO上,而是阻在Future超时wait上。
2. server端的线程模型是什么样的?
这个比较成熟了,现在一般的server都是基于nio,一批io thread负责处理io,一批worker thread负责处理业务。
2. 为什么要用分布式服务框架?
随着互联网的发展,网站应用的规模不断扩大。然后就将应用拆成不相干的几个应用,以提升效率。可是,当应用的不断扩大,应用之间的交互不可避免。则把核心业务抽取出来,作为独立的服务,所以就需要分布式服务框架。当服务越来越多,用于提高机器利用率的资源调度和治理中心(SOA )是关键。
3. Dubbo 框架的架构
Provider:服务提供方,启动时,向注册中心注册自己提供的服务
Consumer:调用远程服务消费方,询问注册中心自己所需的服务。得到地址之后,直接调用与服务打交道
Registry:注册中心,能够动态的注册和发现服务,使服务的位置透明。注册中心的作用就相当于一个电话本
Monitor:统计服务的调用次数和调用时间的监控中心。服务消费者和提供者,定时每分钟发送一次统计数据到监控中心
Container:服务运行容器
注册中心,服务提供者,服务消费者三者之间均为长连接
4. 升级
Deployer : 自动部署服务的本地代理
Repository:仓库用于存储服务应用发布包
Scheduler:调度中西基于访问压力自动增减服务提供者
-
Admin:统一管理控制台
二、Dubbo框架的使用
1. 注册中心的安装(zookeeper)
-
修改hosts文件:vi /etc/hosts
# zookeeper servers 192.168.3.71 为当前Linux 的ip地址,edu-provider-01 是其域名(可随意指定)
192.168.3.71 edu-provider-01
在官网上下载 zookeeper
解压 tar -zxvf zookeeper.tar.gz
然后在 zookeeper 的目录下创建目录 data(mkdir data)、logs(mkdir logs)
在zookeeper/conf 目录下的 zoo_sample.cfg 拷贝一份,命名为 zoo.cfg
-
修改 zoo.cfg 配置文件: vi zoo.cfg
# The number of milliseconds of each tick
tickTime=2000
# The number of ticks that the initial
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between
# sending a request and getting an acknowledgement
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just
# example sakes.
# 是zookeeper 地址
dataDir=/path/zookeeper/data
dataLogDir=/path/zookeepe/logs
# the port at which the clients will connect
clientPort=2181
#2888,3888 are election port
server.1=edu-provider-01:2888:3888
# 2888是zookeeper服务之间通信的端口,3888是zookeeper 与其他应用程序通信的端口,edu-provider-01 是在 hosts 中已映射了 IP 的主机名
在dataDir=/path/zookeeper/data 下创建 myid 文件,并在对应的 IP 机器上输入对应的编号,如果只在单点上安装配置,那么只有一个server.1
-
在对应的用户下修改 vi /home/user/.bash_profile 增加 zookeeper 配置:
# zookeeper env
export ZOOKEEPER_HOME=/path/zookeeper
export PATH=$ZOOKEEPER_HOME/bin:$PATH
是配置文件生效:source /home/user/.hash_profile
-
在防火墙中打开要用到的端口 2181、2888、3888
vi /etc/sysconfig/iptables
-
增加以下3行
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2181 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 2888 -j ACCEPT
-A INPUT -m state --state NEW -m tcp -p tcp --dport 3888 -j ACCEPT
-
重启防火墙: service iptables restart
启动 zookeeper: /path/zookeeper/bin/zookeeper.sh start
输入 jps 查看进程:如果结果含有 QuorumPeerMain 则启动正常
-
可以在 /etc/rc.local 文件加入开机启动的命令
2. dubbo 的配置
1. service-provider 的spring 配置文件
<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"
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">
<!-- 提供方应用信息,用于计算依赖关系 -->
<dubbo:application name="edu-service-user" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<dubbo:registry protocol="zookeeper" address="192.168.3.71:2181" />
<!-- 用dubbo协议在20880端口暴露服务 -->
<dubbo:protocol name="dubbo" port="20880" />
<!-- 用户服务接口,userFacadeService是实现了UserFacadeService接口的类的实例,在这里是通过注解注入到容器里 -->
<dubbo:service interface="cn.cqupt.lansan.dubbotest.facade.user.service.UserFacadeService" ref="userFacadeService" />
</beans>
2.consumer的配置文件
<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"
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">
<!-- 消费方应用名,用于计算依赖关系,不是匹配条件,不要与提供方一样 -->
<dubbo:application name="edu-web-boss" />
<!-- 使用zookeeper注册中心暴露服务地址 -->
<!-- 注册中心地址 -->
<dubbo:registry protocol="zookeeper" address="192.168.3.71:2181" />
<!-- 用户服务接口 -->
<dubbo:reference interface="cn.cqupt.lansan.dubbotest.facade.user.service.UserFacadeService" id="userFacadeService" check="false" />
</beans>
三、Dubbo 管理控制台的安装
1. Dubbo 管理控制台的主要作用:服务治理
Dubbo 管理控制台可以对注册到zookeeper 注册中心的服务 或 服务消费者进行管理,但管控台是否正常对Dubbo 服务没有影响,管控台也不需要高可用,因此可以单节点部署
2. 管理控制台主要包含
路由规则
动态配置
服务降级
访问控制
权重调整
负载均衡管理功能
3. 管理控制台版本
dubbo-admin-2.5.3.war
解压 unzip dubbo-admin-2.5.3.war -d ROOT
然后覆盖掉 tomcat/webapps/ROOT 目录
修改 vi ROOT/WEB-INF/dubbo.properties 文件
dubbo.registry.address=zookeeper://192.168.3.71:2181
# 管理控制台的root 的密码
dubbo.admin.root.password=root
# 管理控制台 guest 的密码
dubbo.admin.guest.password=guest
然后启动 tomcat
-
注意:如果输入 ip:8080 访问不了页面,则代表没有启动成功,可以查看 日志,如果日志有以下异常,则是因为 jdk 版本问题造成的,我试了一下 jdk1.8 会报此错,换成 1.7 就可以了
29-Aug-2016 15:55:23.568 SEVERE [localhost-startStop-1] org.apache.catalina.core.StandardContext.listenerStart Exception sending context initialized event to listener instance of class com.alibaba.citrus.webx.context.WebxContextLoaderListener
org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'uriBrokerService': Cannot create inner bean '(inner bean)' of type [com.alibaba.citrus.service.uribroker.impl.URIBrokerServiceImpl$URIBrokerInfo] while setting bean property 'brokers' with key [0]; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name '(inner bean)#25': Cannot create inner bean 'server' of type [com.alibaba.citrus.service.uribroker.uri.GenericURIBroker] while setting constructor argument; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'server': Error setting property values; nested exception is org.springframework.beans.NotWritablePropertyException: Invalid property 'URIType' of bean class [com.alibaba.citrus.service.uribroker.uri.GenericURIBroker]: Bean property 'URIType' is not writable or has an invalid setter method. Does the parameter type of the setter match the return type of the getter?