文章内容输出来源:拉勾教育Java高薪训练营
1. 前言
1.1 说明
前面已经将三个服务注册到了Nacos服务端了。接下来就要继续改造三个服务的相互调用:验证码服务调用邮箱服务提供的发送邮件,用户服务调用验证码服务提供的校验服务。
原先是直接通过HTTP请求进行调用。而针对于分布式服务来说,HTTP调用相比而言就单薄了些。更多的是使用RPC来调用。因为良好的rpc调用是面向服务的封装,针对服务的可用性和效率等都做了优化。单纯使用http调用则缺少了这些特性。
本文就介绍下如何使用Dubbo来实现服务的远程调用。
1.2 什么是Dubbo
Dubbo是Alibaba开源的一个分布式服务框架,提供高性能和透明化的RPC远程服务调用方案,可以和Spring进行无缝集成。
在Dubbo中所有的的服务调用都是基于接口去进行双方交互的。提供者和消费者双方协定好Dubbo调用中的接口,提供者来提供实现类并且注册到注册中心上。
消费者则只需要引入该接口,并且注册到相同的注册中心上,即可利用注册中心来实现集群感知功能,之后消费者即可对提供者进行调用。
2. 改造邮箱服务
2.1 定义邮箱服务的dubbo服务接口
2.1.1 创建api接口模块
这个模块是用于规范双方接口协定。创建一个maven项目lagou-service-email-api
- 不需要引入其他的依赖
- 创建邮箱业务接口
EmailService
,提供一个发送邮件的接口方法
public interface EmailService {
//发送邮件,发送成功返回true,失败返回false
Boolean send(String email, String code);
}
2.2 改造邮箱服务模块
项目是
lagou-service-email
2.2.1 在pom.xml中引入依赖
包括了dubbo依赖和前面定义的api接口依赖
<dependency>
<groupId>com.yyh</groupId>
<artifactId>lagou-service-email-api</artifactId>
<version>0.0.1</version>
</dependency>
<!--spring cloud+dubbo 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
2.2.2 新建邮箱业务实现类EmailServiceImpl
- 实现
EmailService
接口 - 实现
EmailService
接口的send
方法
(1)将EmailController
中的发送邮件的逻辑拷贝到方法中。因为发送邮件的过程会比较慢,这里简单的另起了一个线程进行异步的调用
public class EmailServiceImpl implements EmailService {
@Autowired
private EmailConfig emailConfig;
@Override
public Boolean send(String email, String code) {
return sendEmail(email, code);
}
private boolean sendEmail(String email, String code) {
MailAccount account = new MailAccount();
account.setHost(emailConfig.getHost());
account.setPort(emailConfig.getPort());
account.setFrom(emailConfig.getFrom());
account.setUser(emailConfig.getUser());
account.setPass(emailConfig.getPass());
new Thread(() -> {
System.out.println("async send email...");
MailUtil.send(account, email, "账号激活邮件", "您的验证码是:" + code + "。有效期10分钟,请尽快输入验证", false);
}).start();
return true;
}
}
- 在实现类上标注上 @Service注解
(1)注意:这个注解是dubbo提供的服务注解@org.apache.dubbo.config.annotation.Service
,用于声明此java服务实现为dubbo服务
import org.apache.dubbo.config.annotation.Service;
@Service
public class EmailServiceImpl implements EmailService {}
2.2.4 去掉EmailController
这个控制类
因为邮箱服务需要被验证码服务调用,接下来会使用rpc进行远程调用,那就不需要再提供http的请求方法了
2.2.5 在配置文件application.yml
上增加dubbo的配置
Dubbo 远程服务需要暴露网络端口,并设定通讯协议
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.yyh.email.service.impl
protocol:
# dubbo 协议
name: dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
port: -1
host: 127.0.0.1
2.3 查看改造后效果
2.3.1 重启邮箱服务项目
2.3.2 在nacos中的lagou-service-email的详情中的元数据信息可以看到此服务的注册信息
3. 改造验证码服务
3.1 定义验证码服务的dubbo服务接口
3.1.1 创建api接口模块
创建一个maven项目lagou-service-code-api
- 不需要引入其他的依赖
- 将
lagou-service-code
的CodeService
迁移过来,创建业务接口
public interface EmailService {
//发送邮件,发送成功返回true,失败返回false
Boolean send(String email, String code);
}
3.2 改造验证码服务模块
项目是
lagou-service-code
3.2.1 在pom.xml中引入依赖
包括了dubbo依赖和前面定义的api接口依赖,因为还要调用邮箱的发送邮件服务,所以还需要把lagou-service-email-api
也引用过来
<dependency>
<groupId>com.yyh</groupId>
<artifactId>lagou-service-code-api</artifactId>
<version>0.0.1</version>
</dependency>
<dependency>
<groupId>com.yyh</groupId>
<artifactId>lagou-service-email-api</artifactId>
<version>0.0.1</version>
</dependency>
<!--spring cloud+dubbo 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
3.2.2 修改验证码业务实现类CodeServiceImpl
- 在实现类上标注上dubbo的 @Service注解
3.2.3 修改控制类CodeController
-
声明验证码业务接口
CodeService
和邮箱业务接口EmailService
(1)注意:这里使用dubbo提供的引用服务注解**@Reference** -
修改创建验证码的请求方法
(1)因为还要暴露给外部web进行http调用,所以保留这方面的配置
(2)修改发送邮件的方法,去掉原先的http调用,使用dubbo远程调用
(3)因为校验验证码的接口后面是要被用户服务进行远程调用,这里就不需要再保留这个请求方法
@RestController
@RequestMapping("codes")
public class CodeController {
@Reference
private CodeService codeService;
@Reference
private EmailService emailService;
@GetMapping("create")
public String create(@RequestParam String email) {
//生成验证码并发送到对应的邮箱中
//生成验证码
String code = codeService.createCode(email);
//发送验证码到邮箱中
Boolean result = emailService.send(email, code);
return result ? "ok" : "error";
}
}
3.2.4 在配置文件application.yml
上增加dubbo配置
包括了两部分:注册配置以及订阅邮箱服务的配置
dubbo:
scan:
# dubbo 服务扫描基准包
base-packages: com.yyh.code.service.impl
protocol:
# dubbo 协议
name: dubbo
# dubbo 协议端口( -1 表示自增端口,从 20880 开始)
port: -1
host: 127.0.0.1
cloud:
# 订阅服务提供方的应用列表,订阅多个服务提供者使用 "," 连接
subscribed-services: lagou-service-email
3.3 查看改造后效果
3.3.1 重启验证码服务项目(邮箱服务也开启)
3.3.2 测试创建验证码方法
curl http://www.test.com/codes/create?email=yaohuiye@126.com
4. 改造用户服务
用户服务是服务提供方,需要调用验证码的校验功能
4.1 在pom.xml中引入依赖
包括了dubbo依赖,因为要调用验证码服务的的校验接口,所以还需要把lagou-service-code-api
也引用过来
<dependency>
<groupId>com.yyh</groupId>
<artifactId>lagou-service-code-api</artifactId>
<version>0.0.1</version>
</dependency>
<!--spring cloud+dubbo 依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-dubbo</artifactId>
</dependency>
4.2 修改控制类UserController
-
声明验证码业务接口
CodeService
,使用**@Reference**注解标识 -
修改注册请求方法中的验证码校验,去掉原先的http调用,使用dubbo远程调用
@Reference
private CodeService codeService;
@PostMapping("register")
public String register(@RequestParam String email,
@RequestParam String password, @RequestParam String code) {
//校验验证码
Integer checkCodeResult = codeService.checkCode(email, code);
if(null != checkCodeResult && checkCodeResult > 0) {
return "error";
}
userService.add(email, password);
return "ok";
}
4.3 在配置文件application.yml
上增加dubbo的配置
包括了订阅验证码服务的配置
dubbo:
cloud:
# 订阅服务提供⽅的应⽤列表,订阅多个服务提供者使⽤ "," 连接
subscribed-services: lagou-service-code