★微服务系列

微服务1:微服务及其演进史

微服务2:微服务全景架构

微服务3:微服务拆分策略

微服务4:服务注册与发现

微服务5:服务注册与发现(实践篇)

微服务6:通信之网关

微服务7:通信之RPC

微服务8:通信之RPC实践篇(附源码)

1 说明

上一节我们我们详细学习了RPC的概念和原理,以及它能够提供的能力。也对目前业内主流的RPC的框架有了一定的了解。接下来以Dobbo为例子,来学习下怎么使用RPC框架来进行服务之间的通信。

2 Dubbo框架功能介绍

Apache Dubbo 是一款分布式微服务开发框架,它提供了 RPC通信 与 微服务治理 两大关键能力。这意味着,使用 Dubbo 开发的微服务,将具备相互之间的远程发现与通信能力, 同时利用 Dubbo 提供的丰富服务治理能力,可以实现诸如服务发现、负载均衡、流量调度等服务治理诉求。同时 Dubbo 是高度可扩展的,用户几乎可以在任意功能点去定制自己的实现,以改变框架的默认行为来满足自己的业务需求。

2.1 服务发现

服务发现,即消费端自动发现服务地址列表的能力,是微服务框架需要具备的关键能力,借助于自动化的服务发现,微服务之间可以在无需感知对端部署位置与 IP 地址的情况下实现通信。

实现服务发现的方式有很多种,Dubbo 提供的是一种 Client-Based 的服务发现机制,通常还需要部署额外的第三方注册中心组件来协调服务发现过程,如常用的 Nacos、Consul、Zookeeper 等,Dubbo 自身也提供了对多种注册中心组件的对接,用户可以灵活选择。

Dubbo 基于消费端的自动服务发现能力,其基本工作原理如下图:

2.2 RPC通信

Dubbo3 提供了 Triple(Dubbo3)、Dubbo2 协议,这是 Dubbo 框架的原生协议。除此之外,Dubbo3 也对众多第三方协议进行了集成,并将它们纳入 Dubbo 的编程与服务治理体系, 包括 gRPC、Thrift、JsonRPC、Hessian2、REST 等。

2.3 服务流量管理

通过 Dubbo 定义的路由规则,实现对流量分布的控制,可以实现 A/B测试、金丝雀发布、蓝绿发布等能力。

2.4 配置管理

描述 Dubbo 支持的配置,Dubbo 的动态配置能力,包含几大类: 启动阶段配置项、服务治理规则、动态配置项。

2.5 部署架构(注册、配置、元数据中心)

作为一个微服务框架,Dubbo sdk 跟随着微服务组件被部署在分布式集群各个位置,为了在分布式环境下实现各个微服务组件间的协作, Dubbo 定义了一些中心化组件,这包括:

  • 注册中心。协调 Consumer 与 Provider 之间的地址注册与发现
  • 配置中心。
    • 存储 Dubbo 启动阶段的全局配置,保证配置的跨环境共享与全局一致性
    • 负责服务治理规则(路由规则、动态配置等)的存储与推送。
  • 元数据中心。
    • 接收 Provider 上报的服务接口元数据,为 Admin 等控制台提供运维能力(如服务测试、接口文档等)
    • 作为服务发现机制的补充,提供额外的接口/方法级别配置信息的同步能力,相当于注册中心的额外扩展。

2.6 高可扩展性

Dubbo 通过 SPI 机制提供了非常灵活的可扩展性

3 Dubbo实现简易的RPC通信

3.1 框架依赖

  • Protocol, Proxy, Service, Container, Registry, Monitor 代表层或模块,蓝色的表示与业务的交互,绿色表示 Dubbo 内部的交互。
  • 主模块 RPC Consumer,RPC Provider, Registry, Monitor 代表部署逻辑拓扑节点。
  • 蓝色虚线为init初始化时调用,红色虚线为async运行时异步调用,红色实线为sync运行时同步调用。
  • Remoting 过程整体都隐含在 Protocol 中。

3.2 核心角色说明

  • Provider 暴露服务的服务提供方
  • Consumer 调用远程服务的服务消费方(负载均衡)
  • Registry 服务注册与发现的注册中心(监控、心跳、踢出、重入)
  • Monitor 服务消费者和提供者在内存中累计调用次数和调用时间,主动定时每分钟发送一次统计数据到监控中心。
  • Service 服务:执行远程调用、数据序列化

3.3 在 SpringBoot 中实践

3.3.1 父项目中引入依赖

首先引入 Zookeeper 和 Dubbo的依赖,Zookeeper的作用是注册与发现,Dubbo的作用是引入RPC通信核心能力

        <!-- 包含了Zookeeper和Dubbo依赖 -->
<dependency>
<groupId>com.alibaba.boot</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>0.2.0</version>
</dependency>

3.3.2 创建module

父项目下面创建三个Module,一个通用模块,一个服务提供者模块,一个服务消费者模块

  • RpcCommon
  • RpcProvider
  • RpcConsume

3.3.3 通用库 RpcCommon

提供了公用的实体和接口,比如这边包含了一个用户信息的实体类和用户信息接口,后面的服务提供者和消费这都可以引用:

/**
* @author brand
* @Description: 用户信息实体
* @Copyright: Copyright (c) 2022
* @Company: Helenlyn, Inc. All Rights Reserved.
* @date 2022/3/5 下午3:59
* @Update Time:
* @Updater:
* @Update Comments:
*/
@Getter
@Setter
public class UserInfo implements Serializable {
private Integer userId;
private String userName;
private Integer age;
private String sex;
}
/**
* @author brand
* @Description: 用户信息接口
* @Copyright: Copyright (c) 2022
* @Company: Helenlyn, Inc. All Rights Reserved.
* @date 2022/3/5 下午5:29
* @Update Time:
* @Updater:
* @Update Comments:
*/
public interface UserInfoService {
UserInfo getUserInfo (int userId) ;
String getHello (int userId) ;
}

3.3.3 服务提供者 RpcProvider

yml文件中的配置信息如下,可以看到我配置的zookeeper地址是127.0.0.1:2181,这是我本地部署到Zookeeper服务,大家可以对应修改下。

scan属性指的是暴露服务的位置,对应位置下的类,只要声明 Service 注解,就会被扫描并暴露出去。

# Dubbo Provider 配置
dubbo:
application:
name: rpc-provider # 发布的dubbo服务名称
registry:
address: 127.0.0.1:2181 # 使用Zookeeper注册中心提供的服务地址,这边可以配置多个,逗号隔开
protocol: zookeeper
protocol:
name: dubbo
port: 20882 # 用dubbo协议在20882端口暴露服务
scan: # 使用注解方式暴露接口,扫描的位置
base-packages: rpcprovider.modules.service

然后编写需要暴露出去的接口的实现,这边需要注意类上引入的注解为com.alibaba.dubbo.config.annotation的Service,

而不是springframework包中的service,这样Service服务才能被注册到dubbo中:

package rpcprovider.modules.service;

import com.alibaba.dubbo.config.annotation.Service;
import rpccommon.dto.UserInfo;
import rpccommon.service.UserInfoService; /**
* @author brand
* @Description:
* @Copyright: Copyright (c) 2022
* @Company: Helenlyn, Inc. All Rights Reserved.
* @date 2022/3/5 下午5:43
* @Update Time:
* @Updater:
* @Update Comments:
*/
@Service
public class UserInfoServiceImpl implements UserInfoService {
@Override
public UserInfo getUserInfo(int userId) {
UserInfo userInfo = new UserInfo();
userInfo.setUserId(userId);
userInfo.setAge(18);
userInfo.setSex("男");
userInfo.setUserName("Brand");
return userInfo;
} @Override
public String getHello(int userId) {
return " Hello, " + userId;
}
}

启动起来看看Zookeeper的效果,是不是被注册到Dubbo中,这边可以用看到,Provider中已经有注册节点了。

[zk: 127.0.0.1:2181(CONNECTED) 68] ls /
[dubbo, zookeeper]
[zk: 127.0.0.1:2181(CONNECTED) 69] ls /dubbo
[rpccommon.service.UserInfoService]
[zk: 127.0.0.1:2181(CONNECTED) 70] ls /dubbo/rpccommon.service.UserInfoService
[configurators, consumers, providers, routers]
[zk: 127.0.0.1:2181(CONNECTED) 71] ls /dubbo/rpccommon.service.UserInfoService/providers
[dubbo%3A%2F%2F172.21.213.159%3A20882%2Frpccommon.service.UserInfoService%3Fanyhost%3Dtrue%26application%3Drpc-provider%26dubbo%3D2.6.2%26generic%3Dfalse%26interface%3Drpccommon.service.UserInfoService%26methods%3DgetHello%2CgetUserInfo%26pid%3D60138%26side%3Dprovider%26timestamp%3D1646535565910]
[zk: 127.0.0.1:2181(CONNECTED) 72]

3.3.4 消费者 RpcConsume

yml文件中的配置信息如下:

# Dubbo Consumer 配置文件
dubbo:
application:
name: rpc-consumer
registry:
address: 127.0.0.1:2181 # 使用Zookeeper注册中心提供的服务地址来获取服务,这边可以多个逗号隔开
protocol: zookeeper

消费者使用注解方式进行RPC调用,这边注意,通过@Reference注解, dubbo会在扫描的时候自动帮我们代理接口,然后通过rpc调用远程服务。如下:

package rpcconsume.modules.service;

import com.alibaba.dubbo.config.annotation.Reference;
import org.springframework.stereotype.Service;
import rpccommon.dto.UserInfo;
import rpccommon.service.UserInfoService; /**
* @author brand
* @Description: 消费者使用注解方式进行RPC调用
* @Copyright: Copyright (c) 2022
* @Company: Helenlyn, Inc. All Rights Reserved.
* @date 2022/3/5 下午6:49
* @Update Time:
* @Updater:
* @Update Comments:
*/
@Service
public class UserInfoConsumer implements UserInfoService {
@Reference
private UserInfoService userInfoService ; @Override
public UserInfo getUserInfo(int userId) {
return userInfoService.getUserInfo(userId);
} @Override
public String getHello(int userId) {
return userInfoService.getHello(userId);
}
}

写一个Controller,通过外部调用,来测试效果

package rpcconsume.modules.controller;

import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import rpccommon.dto.UserInfo;
import rpcconsume.modules.service.UserInfoConsumer; /**
* @author brand
* @Description: 测试消费者效果
* @Copyright: Copyright (c) 2022
* @Company: Helenlyn, Inc. All Rights Reserved.
* @date 2022/3/5 下午6:48
* @Update Time:
* @Updater:
* @Update Comments:
*/
@RestController
@Slf4j
@RequestMapping("/v1.0/consumer")
public class ConsumerController {
@Autowired
private UserInfoConsumer userInfoConsumer ; /**
* 获取用户信息
* @return
*/
@RequestMapping(value = "/userinfo/{user_id}", method = RequestMethod.GET)
public UserInfo getUserInfo(@PathVariable("user_id") int userId) {
return userInfoConsumer.getUserInfo(userId);
} /**
* 获取问候信息
* @return
*/
@RequestMapping(value = "/hello/{user_id}", method = RequestMethod.GET)
public String getHello(@PathVariable("user_id") int userId) {
return userInfoConsumer.getHello(userId);
}
}

查一下Zookeeper 上的消费者信息:

[zk: 127.0.0.1:2181(CONNECTED) 73] ls /dubbo/rpccommon.service.UserInfoService/consumers
[consumer%3A%2F%2F172.21.213.159%2Frpccommon.service.UserInfoService%3Fapplication%3Drpc-consumer%26category%3Dconsumers%26check%3Dfalse%26dubbo%3D2.6.2%26interface%3Drpccommon.service.UserInfoService%26methods%3DgetHello%2CgetUserInfo%26pid%3D60884%26side%3Dconsumer%26timestamp%3D1646536367371]

调用效果:

3.3.5 源代码参考

GitHub地址:https://github.com/WengZhiHua/Helenlyn.Grocery/tree/master/parent

4 总结

RPC通信只是 Dubbo 功能的一部分,像上面介绍的那样,除了RPC通信之外,还有服务注册与发现、配置管理、服务流量治理等,基本能达到一个微服务的基本能力要求。

另外我们还看到,除了Dubbo之外,百度的brpc和Google的gRPC也有很大的受众,也是不错的选择,我们上一章有对主流RPC框架做了对比和分析,可以根据自身的业务特性进行技术选型。

微服务8:通信之RPC实践篇(附源码)的更多相关文章

  1. 【分布式微服务企业快速架构】SpringCloud分布式、微服务、云架构快速开发平台源码

    鸿鹄云架构[系统管理平台]是一个大型 企业.分布式.微服务.云架构的JavaEE体系快速研发平台,基于 模块化.微服务化.原子化.热部署的设计思想,使用成熟领先的无商业限制的主流开源技术 (Sprin ...

  2. 十分钟搭建微服务框架(SpringBoot +Dubbo+Docker+Jenkins源码)

    本文将以原理+实战的方式,首先对“微服务”相关的概念进行知识点扫盲,然后开始手把手教你搭建这一整套的微服务系统. 这套微服务框架能干啥? 这套系统搭建完之后,那可就厉害了: 微服务架构 你的整个应用程 ...

  3. 轻量级C#网络通信组件StriveEngine —— C/S通信开源demo(附源码)

    前段时间,有几个研究ESFramework网络通讯框架的朋友对我说,ESFramework有点庞大,对于他们目前的项目来说有点“杀鸡用牛刀”的意思,因为他们的项目不需要文件传送.不需要P2P.不存在好 ...

  4. IM即时通讯设计 高并发聊天服务:服务器 + qt客户端(附源码)

    来源:微信公众号「编程学习基地」 目录 IM即时通信程序设计 IM即时通讯 设计一款高并发聊天服务需要注意什么 如何设计可靠的消息处理服务 什么是粘包 什么是半包 解决粘包和半包 IM通信协议 应用层 ...

  5. 【JMICRO】 微服务简介及异步RPC体验

    一,为什么写JMicro 印象中初次接触微服务大概是2011年,那会做Eclpise插件开发,网上查看好多关于OSGI的技术文章,发现Spring新出了一个叫Spring-boot的框架,那会没太上心 ...

  6. 微服务架构介绍和RPC框架对比

    微服务架构介绍和RPC框架对比 1.微服务架构 1.1 特征 自动化部署,端点智能化,语言和数据的去中心化控制. 1.2架构 一种将一个单一应用程序开发为一组小型服务的方法,每个服务运行在自己的进程中 ...

  7. 远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo、SpringClound对比

    远程服务调用RPC框架介绍,微服务架构介绍和RPC框架对比,dubbo.SpringClound对比 远程服务调用RPC框架介绍,RPC简单的来说就是像调用本地服务一样调用远程服务. 分布式RPC需要 ...

  8. .net core ——微服务内通信Thrift和Http客户端响应比较

    原文:.net core --微服务内通信Thrift和Http客户端响应比较 目录 1.Benchmark介绍 2.测试下微服务访问效率 3.结果 引用链接 1.Benchmark介绍 wiki中有 ...

  9. 微服务治理平台的RPC方案实现

    导读:本文主要探讨了rpc框架在微服务化中所处的位置,需要解决的问题.同时介绍了用友云微服务治理平台的rpc解决方案,为什么选择该方案.该方案提供的好处是什么.同时也会介绍用友RPC框架的基本结构以及 ...

随机推荐

  1. activiti5.13 框架 数据库表结构说明

    1.结构设计 1.1.    逻辑结构设计 Activiti使用到的表都是ACT_开头的. ACT_RE_*: 'RE'表示repository(存储),RepositoryService接口所操作的 ...

  2. 动态路由与RIP协议

    动态路由与RIP协议 目录 动态路由与RIP协议 一.动态路由(Dynamic Route) 1.动态路由概述 2.动态路由特点 3.动态路由协议 (1)动态路由协议概述 (2)度量值 (3)收敛 4 ...

  3. Java中的多线程你只要看这一篇就够了(引用)

    引 如果对什么是线程.什么是进程仍存有疑惑,请先Google之,因为这两个概念不在本文的范围之内. 用多线程只有一个目的,那就是更好的利用cpu的资源,因为所有的多线程代码都可以用单线程来实现.说这个 ...

  4. Lesson11——NumPy 位运算

    NumPy 教程目录 Lesson11--NumPy 位运算 NumPy "bitwise_" 开头的函数是位运算函数. NumPy 位运算包括以下几个函数: 函数 描述 bitw ...

  5. shell脚本之判断当前内核主版本是否为3,且次版本是否大于10

    [root@localhost ~]# cat uname.sh #!/bin/bash main=`uname -r | awk -F . '{print $1}'` minor=`uname -r ...

  6. 多图|一文详解Nacos参数!

    Nacos 中的参数有很多,如:命名空间.分组名.服务名.保护阈值.服务路由类型.临时实例等,那这些参数都是什么意思?又该如何设置?接下来我们一起来盘它. 1.命名空间 在 Nacos 中通过命名空间 ...

  7. python2写ping监控,自动发现ip

    玩了hostmonitor,老外写的很好.但是不符合国情,只有邮件适合发送. 今天用python 写一个自动发现ip,ping失败报警的程序.(微信和邮件报警) 以前用python写的发微信,发邮件直 ...

  8. 乘风破浪,遇见未来元宇宙(Metaverse)之进入元宇宙世界,虚拟数字人行业洞察报告

    正值元宇宙热潮,虚拟数字人兴起 作为⼀个新兴领域,虚拟数字⼈已经引起市场和资本的⾼度关注,截⾄目前据不完全统计,全球范围已有500+虚拟数字人相关项目获得融资,融资总额超10亿美元,并且融资项目和总额 ...

  9. 数据分析实际案例之:pandas在餐厅评分数据中的使用

    目录 简介 餐厅评分数据简介 分析评分数据 简介 为了更好的熟练掌握pandas在实际数据分析中的应用,今天我们再介绍一下怎么使用pandas做美国餐厅评分数据的分析. 餐厅评分数据简介 数据的来源是 ...

  10. 4.2 K8S超级完整安装配置

    前言: 采坑 k8s有3种安装方式,如下所示: minikube:这是一个k8s集群模拟器,只有一个节点的集群,只为了测试使用,master和node都在一台机器上 直接使用带有容器功能的云平台安装: ...