3.1 Dubbo框架的选型与使用
3.1.1 Dubbo框架的选型
通过表3-1可以看出不同的微服务框架各有优缺点,从分类上来说可以分为两类:服务治理型和多语言型。
表3-1
服务治理型框架包括Dubbo、Dubbox、Motan、Spring Cloud。
多语言型框架包括gRPC、Thrift。
Dubbo是阿里开源的一个高性能优秀的Java服务框架,使应用可通过RPC实现服务的输出和输入功能,同时可以和Spring框架进行无缝集成。
3.1.2 Dubbo框架的使用
在我们正式使用之前,先简单介绍一下Dubbo的架构,对其有一个整体的了解(架构图可参考Dubbo官网)。
通过架构图可以看到,Dubbo提供了三个关键功能:
● 基于接口的远程调用;
● 容错和负载均衡;
● 自动服务注册和发现。
从本章开始我们将正式以支付场景为案例和大家一起探讨微服务从0到1的过程,下面将以一个具体的例子来说明。
1.搭建项目工程结构
项目工程结构分为两个子模块,分别是superpay-tradecenter-core和superpay-tradecenter-facade,这个工程的命名代表支付场景中的交易,具体工程结构如图3-1所示。
图3-1
在图3-1中,我们计划将Dubbo服务的实现类写在superpay-tradecenter-core的facade.impl包中,将接口类写入super-tradecenter-facade工程,这样就将依赖与核心分开了,
2.编写Dubbo服务代码
注:本章约定所有的Dubbo服务类都以facade作为后缀。
建立Dubbo服务前需要先创建服务的接口类,在super-tradecenter-facade模块中写入接口类PayTradeFacade,该接口类目前只有一个支付请求方法payRequest:
public interface PayTradeFacade { /** * 支付请求 * @param payRequestDto * @return */ public PayResponseDto payRequest(PayRequestDto payRequestDto); }
在payRequest方法中有一个入参PayRequestDto,里面主要包括商户支付请求的一些数据,方便后续支付业务进行校验;还有一个参数PayResponseDto,主要是将支付请求的结果返回给调用方,包括返回码和错误描述,代码如下所示。
public class PayRequestDto { private static final long serialVersionUID = -723763178242138577L; //商户订单号 private Long merchantOrderNo; //用户电话 private String phone; //用户姓名 private String userName; //支付金额 private BigDecimal payAmount; //商户号 private String merchantNo; //商户请求时间 private Date merchantReqTime; //订单币种 private String orderCurrency; } public class PayResponseDto { private static final long serialVersionUID = -723763178242138577L; //返回码 private String returnCode; //返回信息 private String returnMsg; }
在superpay-tradecenter-core模块中写入PayTradeFacade接口的实现类,代码如下:
public class PayTradeFacadeImpl implements PayTradeFacade { @Override public PayResponseDto payRequest(PayRequestDto payRequestDto){ PayResponseDto payResponseDto = new PayResponseDto(); payResponseDto.setReturnCode("200"); return payResponseDto; } }
在代码中,为了演示Dubbo使用的效果,我们暂时先将payRequest的返回码设置为200,可以把PayTradeFacade接口类看作支付交易的核心子域,而接口类中的payRequest方法是这个核心子域的内聚方法,向上游提供支付请求服务。
服务代码写完以后,接下来要做的就是如何将服务发布出去,为了项目清晰更容易阅读,我们依然采用配置文件的方式发布服务。现在Dubbo的最新版本是2.5.7,也是本示例中使用的版本,Spring配置文件如下所示。
<! -- 应用名 --> <dubbo:application name="superpay"/> <! -- Dubbo扫描类路径 --> <dubbo:annotation package="com.superpay.core.facade" /> <! -- 连接到哪个本地注册中心 --> <dubbo:registry id="dubbo-registry" address="zookeeper://localhost:2181"/> <! -- 用Dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="28080"/> <! -- 声明需要暴露的服务接口 --> <dubbo:service registry="dubbodemo" timeout="3000" interface="com.tradecenter.facade.PayTradeFacade" ref="payTradeFacade"/> <! -- 服务类定义 --> <bean id="payTradeFacade" class="com.tradecenter.facade.impl.PayTradeFacadeImpl"/>
最终支付交易工程结构的全貌如图3-2所示,这样基于Dubbo的服务提供者代码就已经实现了,接下来写服务调用端代码和配置。
图3-2
3.编写Dubbo调用端代码
调用端的Dubbo Spring配置内容如下:
<! -- 应用名 --> <dubbo:application name="superpay"/> <! -- 连接到哪个本地注册中心 --> <dubbo:registry id="dubbo-registry" address="zookeeper://localhost:2181"/> <! -- 用Dubbo协议在20880端口暴露服务 --> <dubbo:protocol name="dubbo" port="28080"/> <! -- 扫描注解包路径,多个包用逗号分隔,不填pacakge则表示扫描当前ApplicationContext中所有的类 --> <dubbo:annotation package="com.superpay.core.facade" /> <dubbo:reference interface="com.tradecenter.facade.PayTradeFacade" timeout="2000"/>
在调用端假定支付网关业务逻辑调用交易服务的支付请求接口,代码逻辑如下:
@Service public class PayGatewayBizImpl implements PayGatewayBiz { private static final Logger logger = LoggerFactory.getLogger(PayGatewayBizImpl.class); @Autowired private PayTradeFacade payTradeFacade; public void payRequest(PayRequestDto payRequestDto){ PayResponseDto payResponseDto = payTradeFacade.payRequest(payRequestDto); logger.info("打印Dubbo返回响应编码:" + payResponseDto.getReturnCode()); } }
最终打印结果是:
打印Dubbo返回响应编码:200