分布式治理-dubbo-学习笔记

dubbo+spring boot+docker

RPC框架:

RMI/Hessian/webservice

RPC框架的调用错综复杂,dubbo用来维护RPC

F5是硬件负载均衡服务器,如果没有则有负载均衡框架。

 

1.怎么去维护url

通过注册中心去维护url(zookeeper、readis、memcache....)

2.f5硬件负载均衡器的单点压力大

软负载均衡

3.怎么去整理出服务之间的依赖关系

自动去整理出各个服务之间的依赖

4.如果服务器的调用量越来越大,服务器的容量问题怎么去评估,扩容的指标

需要一个监控平台、可以监控调用量、响应时间

 

dubbo是什么

dubbo是一个分布式的服务框架、提供高性能的以及透明化的rpc远程调用解决方案、以及SOA服务治理方案。

dubbo的核心部分:

远程通信

集群容错

服务的自动发现

负载均衡

dubbo的架构

核心角色

provider

Consumer

Registry

Monitor

Container

 

 

docker是一种虚拟化容器

高性能的刀片机

32G内存 16核心

可以虚拟化出

4G 2核心 8台

用docker来存储

 

PAAS(platform-as-a-service):我只要部署软件即可

IAAS(infrrastucturre-as-a-service):基础设施平台,相当于提供了一台服务器

SAAS(软件即服务)

 

admin控制台的安装

1.下载dubbo源码

2.找到dubbo-admin

3.修改webapp/web-inf/dubbo.properties

dubbo.registry.address=zk的集群地址

控制中心是用来做服务治理的,比如控制服务的权重,路由

 

simple监控中心

monitor也是一个dubbo服务,所以也会有端口和url

 

修改/conf目录下dubbo.properties

dubbo.registry.address=zk的集群地址

监控服务的调用次数、调用关系、响应时间

 

telnet命令

telnet localshot 20880

dubbo>ls 或 cd com.gupao.IOrderServices 或 pwd 或invoke com.gupao.IOrderService.doOrder({name:'a'})

用Telnet命令不受监控

 

 

启动服务检查

<!--check=false订阅失败则出错--> <dubbo:registry address="zookeeper://192.168.88.131:2181?backup=192.168.88.132:2181,192.168.88.133:2181"/> <!--check=false如果服务没有提供则报错--> <dubbo:consumer check="false"></dubbo:consumer> <!--check=false如果提供方没有启动的时候默认会检查所依赖的服务是否正常提供服务,如果check为false,表示启动的时候不去检查,当服务出现循环依赖的时候,check设置为检查--> <dubbo:reference id="sayHello" interface="cn.lxc.ISayHello" timeout="1200000" check="false" protocol="hessian"></dubbo:reference>

 

dubbo多协议支持

需要导入jetty的相关包,

com.caucho:hessian:4.0.38 javax.servlet:servlet-api:2.5 org.mortbay.jetty:jetty:6.1.26

 

<!--多协议--> <dubbo:protocol name="dubbo" port="20880" server="jetty"/> <!--多协议--> <dubbo:protocol name="hessian" port="8090" server="jetty"/> <!--指定协议,允许指定多个协议,中间用逗号隔开,dubbo会发布两个url--> <dubbo:service interface="cn.lxc.ISayHello" ref="sayhello" protocol="hessian,dubbo"></dubbo:service>

 

dubbo多注册中心支持

<!--注册中心可以有多个需要用id来区分--> <dubbo:registry id="zkOne" address="zookeeper://192.168.88.131:2181?backup=192.168.88.132:2181,192.168.88.133:2181"/> <dubbo:registry id="zkTwo" protocol="zookeeper" address="192.168.88.132:2181"/> <dubbo:service interface="cn.lxc.ISayHello" ref="sayhello" protocol="hessian" registry="zkOne"></dubbo:service>

 

dubbo多版本支持

<!--provider端--> <dubbo:service interface="cn.lxc.ISayHello" ref="sayhello" protocol="hessian" registry="zkOne" version="1.0"/> <!--consumer端--> <dubbo:reference id="sayHello" interface="cn.lxc.ISayHello" timeout="1200000" check="false" protocol="hessian" version="2.0"/>

dubbo异步调用(只支持dubbo序列化协议)

<!--consumer端--> Future<String> response=RpcContext.getContext().getFuture(); String str=response.get();

主机绑定(只能绑定一个)

表示与每个服务发布的url相对应的主机ip(本地合法ip)

<dubbo:protocol name="dubbo" port=20880 localhost="192.168.192.12">

服务只订阅

可能所有的服务都共有一个注册中心,如果有一个服务没有做好正在开发阶段,那么调用者就不能启动,为了解决这个问题就有了服务只订阅。

<dubbo:registry address="zookeeper://192.168.88.131:2181?backup=192.168.88.132:2181,192.168.88.133:2181" register="false"/>

服务只注册

只提供服务不订阅服务

<dubbo:registry address="zookeeper://192.168.88.131:2181?backup=192.168.88.132:2181,192.168.88.133:2181" subscribe="false"/>

负载均衡

Random(默认是随机负载均衡)

roundRobin轮询:按照公约后的权重设置轮询比率

leastActive LoadBalance 最少活跃调用数,对于响应时间比较短的服务会优先。

Consistent LoadBalance 一致性哈希

<dubbo:l >

连接超时timeout

必须要设置服务处理的超时时间

<dubbo:service interface="" timeout="2000">

 

配置优先级

消费端优先,之后是服务端

集群容错策略

failover cluster 默认策略 失败的时候自动切换并重试其他服务器。通过retries=num。来设置容错次数默认等于2表示一个服务最大访问三次(第一次不算重试)

failfast cluster 快速失败 只发起一次调用:写操作。比如新增记录的时候,即非幂等请求是建议使用

failsafe cluster 失败安全 出现异常时,直接忽略异常

failback cluster 失败自动恢复 后台记录失败请求,定时重发。

forking cluster 并行调用多个服务器,只要一个成功,就返回。只能应用在读请求。

broadcast cluster 广播调用所有提供者,逐一调用,其中一台报错就返回异常。

 

<dubbo:service interface="cn.lxc.ISayHello" ref="sayhello" protocol="hessian" registry="zkOne" version="1.0"/>

 

 

服务最佳实践

分包

1.服务接口、请求服务模型、异常信息都放在api中,符合重用发布等价原则,共同重用原则

2.api里面放入spring的引用配置。也可以放在模块的包目录下,com.gupao.vip.mic.order/***.reference.xml

粒度

1.尽可能把接口设置成粗粒度,每个服务方法代表一个独立的功能,而不是某个功能的步骤,否则就会涉及到分布式事务

2.服务接口建议以业务场景为单位划分。并对相近事务做抽象,防止接口暴增

3.不建议使用过于抽象的通用接口范型,接口没有明确的语义,带来后期维护困难

版本

1.每个接口都应该定义版本,为后续的兼容性提供前瞻性的考虑version

2.建议使用两位版本号、因为三位版本号表示兼容性升级,只有不兼容是才需要变更服务

3.当接口做到不兼容升级的时候,先升级一半或者一台提供者为新版本,在将消费全部升级

 

推荐用法

在provider端尽可能配置consumer端的属性

人比如:timeout、线程池大小、loadbalance

配置管理员信息

application上配置的owner、owner建议配置2个人以上。因为owner都能在监控中心看到

配置缓存环境

<!--缓存,如果zk不可用则会缓存服务的所有的url--> <dubbo:register file="d:/dubbo.cache">

 

源码

dubbo-admin //控制台

dubbo-cluster

common //工具

config //配置

filter 、、过滤

registry 注册中心

remoting 通讯(可以认为是dubbo协议的实现)

rpc

simple 简单的监控中心

 

基于spring配置文件的扩展的话

namespaceHandler 注册BeanDefinitionParser 利用它来解析

beanDefinitionParser

需要写以上两个类(在config项目下的spring相关)

 

 

InitializingBean, 当spring容器初始化后会调用afterPropertiesSet

DisposableBean, spring销毁会destory

ApplicationContextAware, 主动注入applicationContext对象

ApplicationListener<ContextRefreshedEvent>, 事件监听

BeanNameAware, 初始化完后获得id属性

ApplicationEventPublisherAware

DubboBeanDefinitionParser 进行上下文解析到对象,对于ProtocolConfig、ServiceBean、ProviderConfig和ConsumerConfig单独做处理以外其他的都走通用的逻辑进行成员赋值

for (Method setter : beanClass.getMethods()) { String name = setter.getName(); if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(setter.getModifiers())

if (ProtocolConfig.class.equals(beanClass)) { for (String name : parserContext.getRegistry().getBeanDefinitionNames()) { BeanDefinition definition = parserContext.getRegistry().getBeanDefinition(name); PropertyValue property = definition.getPropertyValues().getPropertyValue("protocol"); if (property != null) { Object value = property.getValue(); if (value instanceof ProtocolConfig && id.equals(((ProtocolConfig) value).getName())) { definition.getPropertyValues().addPropertyValue("protocol", new RuntimeBeanReference(id)); } } } } else if (ServiceBean.class.equals(beanClass)) { String className = element.getAttribute("class"); if (className != null && className.length() > 0) { RootBeanDefinition classDefinition = new RootBeanDefinition(); classDefinition.setBeanClass(ReflectUtils.forName(className)); classDefinition.setLazyInit(false); parseProperties(element.getChildNodes(), classDefinition); beanDefinition.getPropertyValues().addPropertyValue("ref", new BeanDefinitionHolder(classDefinition, id + "Impl")); } } else if (ProviderConfig.class.equals(beanClass)) { parseNested(element, parserContext, ServiceBean.class, true, "service", "provider", id, beanDefinition); } else if (ConsumerConfig.class.equals(beanClass)) { parseNested(element, parserContext, ReferenceBean.class, false, "reference", "consumer", id, beanDefinition); } Set<String> props = new HashSet<>(); ManagedMap parameters = null; for (Method setter : beanClass.getMethods()) { String name = setter.getName(); if (name.length() > 3 && name.startsWith("set") && Modifier.isPublic(setter.getModifiers())

 

 

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值