写在最前
如果这个项目让你有所收成,记住 Star 关注哦,这对我是非常不错的鼓舞与支撑。
源码地址(后端):gitee.com/csps/mingyu…
源码地址(前端):gitee.com/csps/mingyu…
文档地址:gitee.com/csps/mingyu…
长途调用
长途调用为分布式系统供应了一种便利、高效和可靠的通讯方法,使得不同部分的组件可以协同工作,并完结代码的模块化、解耦和重用。它是构建可扩展、活络和可保护的分布式系统的重要东西和技能。
为什么要运用长途调用?
- 分布式系统:在分布式系统中,不同的组件或服务可能分布在不同的机器或进程中。运用长途调用可以使这些组件可以通过网络互相通讯,进行数据交换和协作,完结系统的功用和事务逻辑。
- 模块化和解耦:长途调用使得系统的各个模块可以独立开发和安置,通过定义清晰的接口和协议,模块之间可以解耦并独立演化。这样,系统的不同部分可以独立进行批改、升级或替换,而不会对其他部分产生影响。
- 代码重用性:通过长途调用,可以将某些功用或服务封装为可复用的模块,供多个应用程序或系统共享和调用。这样可以避免重复开发相同的功用,前进代码的重用性和开发功率。
- 扩展性和弹性:长途调用可以完结系统的弹性扩展和水平扩展。当系统负载增加时,可以通过安置更多的服务实例,并运用负载均衡器进行流量分发,以应对更高的并发央求。
- 服务办理和监控:运用长途调用结构可以集成服务办理和监控功用,例如服务注册与发现、负载均衡、熔断器、日志记载等。这些功用可以供应更好的可用性、功用和可保护性,一同也可以帮助开发人员进行系统的监控和毛病排查。
技能选型
OpenFeign 与 Dobbo 3 都是优异的微服务架构下的长途调用结构,各有千秋。
维度 | OpenFeign | Dobbo 3 |
---|---|---|
类型 | 依据 Java 的声明式 Web 服务客户端 | RPC(长途进程调用)结构 |
协议支撑 | 支撑 RESTful API,一般依据 HTTP 协议进行通讯 | 支撑多种长途通讯协议,不只包含 Dubbo 自有的二进制协议,还支撑 HTTP、gRPC等,这使得 Dubbo 3 在不同场景下更加活络 |
编程模型 | 声明式的 API 定义和调用方法,通过 Java 接口和注解来描绘服务接口和方法,运用起来更加简练和直观 | 声明式的 API,但更多情况下运用 XML 配备或注解配备,一同支撑传统的编程式调用方法。 |
服务办理 | 集成了 Netflix 的负载均衡器 Ribbon,但相较 Dubbo 3在服务办理方面较为简略。 | 供应了更多功用,如负载均衡、服务注册与发现、熔断器等,适用于大规模分布式系统的构建。 |
生态和社区 | 2019年 Netflix 公司宣告 Feign 组件正式进入停更保护状况,所以 Spring 官便利推出了一个名为 OpenFeign 的组件作为 Feign 的代替方案。 | 2011年开源,2012年发布2.5.3版本后中止更新,2017年阿里重启 dubbo 项目,现在由 Apache 软件基金会进行保护和展开,具有安稳的社区支撑。 |
OpenFeign + OkHttp3
本架构将选用 OpenFeign + OkHttp3 作为长途调用东西。
- 声明式 API 定义:OpenFeign 供应了声明式的 API 定义方法,运用接口和注解来描绘服务接口和方法。这使得代码更加简练、可读性更强,而且开发人员可以更专心于事务逻辑而不是底层的 HTTP 央求细节。
- 健壮的 HTTP 功用:OkHttp3 是一个功用健壮的 HTTP 客户端库,供应了丰厚的功用和特性,如联接池办理、央求和照应阻挠器、央求重试、缓存等。通过将 OpenFeign 与 OkHttp3 结合运用,可以运用 OkHttp3 的这些功用来处理HTTP 央求和照应,前进功用和可靠性。
- 高功用和可扩展性:OkHttp3 被广泛认为是一个高功用的 HTTP 客户端,具有优异的功用和功率。它支撑并发央求、联接复用和异步操作等,可以满足大规模和高并发的需求。一同,OkHttp3 也具备很好的可扩展性,可以通过自定义阻挠器和插件来扩展和定制其功用。
- 网络层配备:OkHttp3 供应了丰厚的网络层配备选项,如联接超时、读写超时、署理设置等。通过运用 OkHttp3 作为OpenFeign 的底层 HTTP 客户端,可以活络地配备和办理网络层的行为,以满足特定的需求。
- 生态和社区支撑:OpenFeign 和 OkHttp3 都是广受欢迎的开源项目,具有活跃的社区和安稳的保护。这意味着开发人员可以从社区中取得支撑、文档和更新的功用。
综上所述,将 OpenFeign 与 OkHttp3 结合运用可以享受到 OpenFeign 声明式 API 定义的便利性,并运用 OkHttp3 供应的健壮的 HTTP 功用和功用优势。这样的组合可以简化代码、前进功用,并为开发人员供应更好的可扩展性和配备活络性。
增加 mingyue-common-feign
引入依托
<dependencies>
<dependency>
<groupId>com.csp.mingyue</groupId>
<artifactId>mingyue-common-core</artifactId>
</dependency>
<!-- SpringCloud Openfeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<!-- okhttp 扩展 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
<!-- LB 扩展 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>
</dependencies>
自定义注解
覆盖 @EnableFeignClients 注解,默许 basePackages,客户端直接运用 @EnableMingYueFeignClients 注解即可,无须再指定 basePackages。
import org.springframework.cloud.openfeign.EnableFeignClients;
import org.springframework.cloud.openfeign.FeignClientsConfiguration;
import java.lang.annotation.Documented;
import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;
/**
* 翻开 Feign Client
*
* @author Strive
* @date 2023/7/4
*/
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@Documented
@EnableFeignClients
public @interface EnableMingYueFeignClients {
/**
* Alias for the {@link #basePackages()} attribute. Allows for more concise annotation
* declarations e.g.: {@code @ComponentScan("org.my.pkg")} instead of
* {@code @ComponentScan(basePackages="org.my.pkg")}.
* @return the array of 'basePackages'.
*/
String[] value() default {};
/**
* Base packages to scan for annotated components.
* <p>
* {@link #value()} is an alias for (and mutually exclusive with) this attribute.
* <p>
* Use {@link #basePackageClasses()} for a type-safe alternative to String-based
* package names.
* @return the array of 'basePackages'.
*/
String[] basePackages() default { "com.csp.mingyue" };
/**
* Type-safe alternative to {@link #basePackages()} for specifying the packages to
* scan for annotated components. The package of each class specified will be scanned.
* <p>
* Consider creating a special no-op marker class or interface in each package that
* serves no purpose other than being referenced by this attribute.
* @return the array of 'basePackageClasses'.
*/
Class<?>[] basePackageClasses() default {};
/**
* A custom <code>@Configuration</code> for all feign clients. Can contain override
* <code>@Bean</code> definition for the pieces that make up the client, for instance
* {@link feign.codec.Decoder}, {@link feign.codec.Encoder}, {@link feign.Contract}.
*
* @see FeignClientsConfiguration for the defaults
*/
Class<?>[] defaultConfiguration() default {};
/**
* List of classes annotated with @FeignClient. If not empty, disables classpath
* scanning.
* @return
*/
Class<?>[] clients() default {};
}
Nacos 翻开配备
application-common.yml
# feign 配备
feign:
# 启用 okhttp 作为网络央求结构
okhttp:
enabled: true
# 关闭 httpclient 作为网络央求结构
httpclient:
enabled: false
client:
config:
# 将调用的微服务称谓改成 default 就配备成大局的了
default:
# 相当于 Request.Optionsn 联接超时时刻
connectTimeout: 10000
# 相当于 Request.Options 读取超时时刻
readTimeout: 10000
compression:
request:
# 配备央求 GZIP 紧缩
enabled: true
response:
# 配备照应 GZIP 紧缩
enabled: true
批改 mingyue-system-api
引入依托
<dependency>
<groupId>com.csp.mingyue</groupId>
<artifactId>mingyue-common-feign</artifactId>
</dependency>
长途调用用户服务
import com.csp.mingyue.common.core.constant.ServiceNameConstants;
import com.csp.mingyue.common.core.vo.R;
import com.csp.mingyue.system.api.entity.SysUser;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* 长途调用用户服务
*
* @author Strive
* @date 2023/7/3 09:48
*/
@FeignClient(contextId = "remoteUserService", value = ServiceNameConstants.SYSTEM_SERVICE)
public interface RemoteUserService {
/**
* 通过用户名查询用户、角色信息
* @param username 用户名
* @return R
*/
@GetMapping(value = "/sysUser/getSysUserInfoByUsername")
R<SysUser> getSysUserInfoByUsername(@RequestParam(value = "username") String username);
}
mingyue-auth 长途调用 mingyue-system
引入依托
<!-- 系统服务 API -->
<dependency>
<groupId>com.csp.mingyue</groupId>
<artifactId>mingyue-system-api</artifactId>
</dependency>
批改登录
public SaTokenInfo login(PasswordLoginDto dto) {
R<SysUser> userInfoResp = remoteUserService.getSysUserInfoByUsername(dto.getUsername());
if (Objects.isNull(userInfoResp) || Objects.isNull(userInfoResp.getData())) {
return null;
}
SysUser userInfo = userInfoResp.getData();
if (dto.getUsername().equals(userInfo.getUsername()) && dto.getPassword().equals(userInfo.getPassword())) {
// 第1步,先登录上
StpUtil.login(10001);
// 第2步,获取 Token 相关参数
SaTokenInfo tokenInfo = StpUtil.getTokenInfo();
return tokenInfo;
}
return null;
}
发动检验
curl -X 'POST' \
'http://mingyue-gateway:9100/auth/login' \
-H 'accept: */*' \
-H 'Content-Type: application/json' \
-d '{
"username": "mingyue",
"password": "123456"
}'
回来示例
{
"code": 200,
"msg": "登录成功",
"data": "2GcAFW7UZ0XJjDe5H76CBAtj7zc7bm8S"
}
翻开或关闭 OkHttp3
默许的HttpURLConnection
是 JDK 自带的,并不支撑联接池,如果要完结联接池的机制,还需要自己来办理联接对象。OkHttp3 自带联接池办理,提高吞吐量。
中心依托
<!-- okhttp 扩展 -->
<dependency>
<groupId>io.github.openfeign</groupId>
<artifactId>feign-okhttp</artifactId>
</dependency>
运用方法
Nacos 配备 application-common.yml
# feign 配备
feign:
# 启用 okhttp 作为网络央求结构
okhttp:
# true 翻开 / false 关闭
enabled: true
验证是否翻开
查看 Client 完结,实践发送央求是由 Feign 中的
Client
接口完结类去处理的,默许运用的是 Defalut 类,该类运用的是HttpURLConnection
。
默许完结,关闭 okhttp 后,对此方法断点查看是否进入
@Override
public Response execute(Request request, Options options) throws IOException {
HttpURLConnection connection = convertAndSend(request, options);
return convertResponse(connection, request);
}
翻开 OkHttpClient 类,查看 OkHttp3 源码,找到 execute 方法。翻开 okhttp 后,对此方法断点查看是否进入
@Override
public feign.Response execute(feign.Request input, feign.Request.Options options)
throws IOException {
okhttp3.OkHttpClient requestScoped = getClient(options);
Request request = toOkHttpRequest(input);
Response response = requestScoped.newCall(request).execute();
return toFeignResponse(response, input).toBuilder().request(input).build();
}
小结
至此,mingyue-auth
现已可以通过长途调用获取 mingyue-system
服务。下一节,网关增加接口阻挠,引入白名单列表。