文章目录
分布式架构实践:使用Dubbo实现服务治理
1、什么是分布式系统架构,演进的各个阶段
4个方面的问题:高可用、高并发、高性能,服务如何管理
-
客户端如何访问这么多的服务(nginx,tomcat多外暴http端口?)
通过API网关,dubbo,zuul
-
服务与服务之间是如何通信的?
- 同步通信(http,RPC)
- 异步通信(MQ)
-
这么多的服务如何管理
- 服务治理:什么时候服务上线,什么时候服务下线,这就需要服务的注册与发现
-
如果垂直架构里某个功能模块出现宕机或不可用,这个时候我们已经分布式了
- 容错重试机制
- 服务的降级:写库存、同步支付信息、邮件或其他方式同步给用户
- 服务限流
- 服务熔断
2、使用Dubbo实现服务治理,Dubbo的应用场景
3、Dubbo的应用架构及内部结构调用关系
3.1.节点角色说明
节点 | 角色说明 |
---|---|
Provider | 暴露服务的服务提供方 |
Consumer | 调用远程服务的服务消费方 |
Registry | 服务注册与发现的注册中心 |
Monitor | 统计服务的调用次数和调用时间的监控中心 |
Container | 服务运行容器 |
Dubbo对于服务的管理和支持,可以理解为让远程调用就像我们本地调用一样简单
4、基于Springboot搭建Dubbo环境和服务
管理中心
zookeeper搭建好
1、下载zookeeper修改配置
dataDir=/Users/gavin/Documents/zookeeper-alone/data
dataLogDir=/Users/gavin/Documents/zookeeper-alone/log
2、启动在bin目录下:./zkServer.sh start
启动dubbo-admin:java -jar dubbo-admin-0.0.1-SNAPSHOT.jar
server.port=7001
spring.velocity.cache=false
spring.velocity.charset=UTF-8
spring.velocity.layout-url=/templates/default.vm
spring.messages.fallback-to-system-locale=false
spring.messages.basename=i18n/message
spring.root.password=root
spring.guest.password=guest
dubbo.registry.address=zookeeper://127.0.0.1:2181
#注意注册中心地址
4.1. provider的配置
依赖包放在im-common-util下
<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
</dependency>
<dependency>
<groupId>com.101tec</groupId>
<artifactId>zkclient</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-framework</artifactId>
</dependency>
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
</dependency>
<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
</exclusions>
</dependency>
做yaml配置
dubbo:
application:
name: product-manage
protocol:
name: dubbo
port: 20880
registry:
protocol: zookeeper
address: 127.0.0.1:2181
scan:
base-packages: com.icodingedu.mall
#也可以不扫包,用@EnableDubbo在启动类上
托管实现类
import org.apache.dubbo.config.annotation.Service;
@Service
@Component
4.2. consumer配置
yaml配置
dubbo:
application:
name: admin-web
protocol:
name: dubbo
registry:
protocol: zookeeper
address: 127.0.0.1:2181
consumer:
check: false
consumer调用,调用传递的对象需要序列化
public class ImProduct implements Serializable {
private static final long serialVersionUID = -4298312059463116715L;
调用方式
@Controller
public class RouterController {
@Reference
ProductService productService;
public R getProductList(){
return R.returnOK(200,"ok",productService.queryProductList(1,3));
}
}
5、Dubbo服务治理之服务高可用
如果运行中zookeeper挂了,还是可以消费dubbo暴露的服务
如果zookeeper实现集群后,任意一台宕机后会自动切换到另一台
虽然可以继续访问暴露的服务,但不能新注册了
6、Dubbo实现服务负载均衡机制&粘滞连接
配置的调用顺序
- 方法级优先,接口级次之,最后是全局
- 如果级别一样,则消费方优先,提供方次之
两个都可以通过配置进行处理
@Reference(loadbalance = "roundrobin",sticky=true) //固定到一个服务上
ProductService productService;
7、Dubbo实现集群&服务容错
服务容错
8、Dubbo实现服务降级:Admin管理降级,Mock返回,本地存根主动降级
Mock数据配置,也是在consumer端
//这个是在调用的接口注解
@Reference(mock = "com.icodingedu.mall.admin.service.impl.ProductServiceMock")
//Mock实现类
public class ProductServiceMock implements ProductService {
@Override
public List<ImProduct> queryProductList(int pageNum, int pageSize) {
List<ImProduct> imProductList = new ArrayList<ImProduct>();
ImProduct imProduct = new ImProduct();
imProduct.setProductTitle("Mock Product");
imProductList.add(imProduct);
return imProductList;
}
}
本地存根就可以做到主动降级,在消费者consumer端
@Reference(mock = "com.icodingedu.mall.admin.service.impl.ProductServiceMock",stub = "com.icodingedu.mall.admin.service.impl.ProductServiceStub")
ProductService productService;
//stub的实现类
public class ProductServiceStub implements ProductService {
//远端调用的服务
private final ProductService productService;
//dubbo会通过这个有参的构造函数注入远程调用
public ProductServiceStub(ProductService productService){
this.productService = productService;
}
@Override
public List<ImProduct> queryProductList(int pageNum, int pageSize) {
System.out.println("==============stub service=============");
return productService.queryProductList(pageNum,pageSize);
}
}
9、Dubbo实现版本控制灰度发布:version,group
如果说有一个功能我还处于测试中,这个时候我们上线了希望只让一部分人使用
@Reference(version = "2.0.0")
@Reference(group = "gp1")
@Service(version = "2.0.0")
@Reference(group = "gp2")
group和version类似,但是group提供一个分组合并的功能
###10、Dubbo实现隐式传参
//consumer
RpcContext.getContext().setAttachment("id","gavin-admin-web");
//provider
String appid = RpcContext.getContext().getAttachment("id");