015-从零搭建微服务-远程调用(一)

news2024/11/23 20:11:28

写在最前

如果这个项目让你有所收获,记得 Star 关注哦,这对我是非常不错的鼓励与支持。

源码地址(后端):https://gitee.com/csps/mingyue

源码地址(前端):https://gitee.com/csps/mingyue-ui

文档地址:https://gitee.com/csps/mingyue/wikisapplication-common.yml

远程调用

远程调用为分布式系统提供了一种方便、高效和可靠的通信方式,使得不同部分的组件能够协同工作,并实现代码的模块化、解耦和重用。它是构建可扩展、灵活和可维护的分布式系统的重要工具和技术。

为什么要使用远程调用?

  1. 分布式系统:在分布式系统中,不同的组件或服务可能分布在不同的机器或进程中。使用远程调用可以使这些组件能够通过网络相互通信,进行数据交换和协作,实现系统的功能和业务逻辑。
  2. 模块化和解耦:远程调用使得系统的各个模块能够独立开发和部署,通过定义清晰的接口和协议,模块之间可以解耦并独立演化。这样,系统的不同部分可以独立进行修改、升级或替换,而不会对其他部分产生影响。
  3. 代码重用性:通过远程调用,可以将某些功能或服务封装为可复用的模块,供多个应用程序或系统共享和调用。这样可以避免重复开发相同的功能,提高代码的重用性和开发效率。
  4. 扩展性和弹性:远程调用可以实现系统的弹性扩展和水平扩展。当系统负载增加时,可以通过部署更多的服务实例,并使用负载均衡器进行流量分发,以应对更高的并发请求。
  5. 服务治理和监控:使用远程调用框架可以集成服务治理和监控功能,例如服务注册与发现、负载均衡、熔断器、日志记录等。这些功能可以提供更好的可用性、性能和可维护性,同时也可以帮助开发人员进行系统的监控和故障排查。

技术选型

OpenFeign 与 Dobbo 3 都是优秀的微服务架构下的远程调用框架,各有千秋。

维度OpenFeignDobbo 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

image-20230705165355874

默认实现,关闭 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 服务。下一节,网关增加接口拦截,引入白名单列表。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/721490.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

如何利用Spine制作简单的2D骨骼动画

在2D游戏中&#xff0c;我们经常看到各种各样的角色动画。动画能给游戏带来生机和灵气。创作一段美妙的动画&#xff0c;不仅需要强大的软件工具&#xff0c;更需要一套完善的工作流程。 Spine就是一款针对游戏开发的2D骨骼动画编辑工具。Spine 可以提供更高效和简洁 的工作流…

【STM32智能车】寻迹模块

【STM32智能车】寻迹模块 寻迹模块 传感器原理接线说明 智能车寻迹是一种机器人控制技术&#xff0c;它通过使用传感器和程序算法&#xff0c;使汽车能够在行驶过程中识别出路径上的黑线&#xff0c;并沿着该线路行驶。 智能车寻迹常用于竞赛或教育用途&#xff0c;可以提高学生…

【学习心得】Virtual Studio Code下载安装与简单设置

一、下载 1、vs code 官网&#xff1a;https://code.visualstudio.com/ 二、安装 1、双击安装文件开始安装。 2、同意协议开始下一步。 3、选择你自己想要安装的路径。 4、勾选这三个&#xff0c;方便右键在vs code 中打开文件或文件夹。 5、安装步骤几乎没有坑&#xff0c;直…

探究低代码开发平台的价值所在,为企业带来哪些优势?

随着数字化转型的加速&#xff0c;企业和组织需要以更快的速度交付新的软件应用程序&#xff0c;以保持竞争力和创新性。然而&#xff0c;传统的软件开发模式已经不再适用于当前的快节奏商业环境。在这种背景下&#xff0c;低代码开发平台日益成为软件开发的热门趋势&#xff0…

【JavaWeb基础】三层架构

一、知识点整理 三层架构的含义 Controller: 控制层,接收前端发送的请求,对请求进行处理,并响应数据。 Service:业务逻辑层,处理具体的业务逻辑。 Dao(Data Access Object): 数据访问层(持久层),负责数据访问操作,包括数据的增、删、改、查。 二、代码实现 原EmpController.…

spring整合logBack日志框架:

1. SLF4J简介 SLF4J&#xff08;Simple Logging Facade for Java&#xff09;是一种日志规范&#xff0c;类似于JDBC&#xff0c;我们常用的日志log4j、logback等都实现了这个规范&#xff0c;所以我们可以直接使用SLF4J的规范来使用日志。 2. logback和log4j 它们是同一个作…

【hadoop】大数据的几个基本概念

大数据的几个基本概念 数据仓库的基本概念数据仓库与大数据OLTP与OLAP 数据仓库的基本概念 数据仓库&#xff0c;英文名称为Data Warehouse&#xff0c;可简写为DW或DWH。数据仓库&#xff0c;是为企业所有级别的决策制定过程&#xff0c;提供所有类型数据支持的战略集合。 本…

堆排序算法及其稳定性分析

堆排序算法及其稳定性分析 什么是堆排序&#xff1f; 堆排序是利用数据结构堆而设计的一种排序算法。 堆分为两种&#xff0c;大顶堆和小顶堆。 所谓大顶堆就是每个节点的值都大于或者等于其左右孩子节点的值。 小顶堆则是相反的&#xff0c;每个节点的值都小于或者等于其…

超全整理,接口测试实战详细(实例)一篇打通...

目录&#xff1a;导读 前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09; 前言 1、接口测试范围 …

Git无法上传删除 Commit里面有大文件

1.Bug描述 因为在一次提交中不小心把一个打包的aab文件弄到commit文件里了&#xff0c;于是在上传的时候push rejected 了。 因为GitHub的文件上限是100M&#xff0c;但是打的包太大了&#xff0c;有170M&#xff0c;所以是不能上传的&#xff0c;但是又是已经在Commit历史中了…

rsync增量备份工具

目录 一、概述 二、配置 rsync 源服务器 1.查看rsync配置文件位置 2.修改 /etc/rsync.conf 配置文件 3.为备份账户创建数据文件 4.保证所有用户对源目录都有读取权限 5.启动 rsync 服务 三、发起端 1.rsync命令 2.将指定的资源远程同步到本地/opt 目录下进行备份。 3.将…

【Docker】docker安装nginx及端口映射相关配置

前言&#xff1a; 最近&#xff0c;在一台新服务器上准备运行一个前端vue项目&#xff0c;服务器上安装了docker&#xff0c;想要尝试试通过docker安装nginx的并运行项目&#xff0c;以下是操作步骤 操作步骤&#xff1a; 一、安装nginx 1、拉取镜像 从docker仓库里拉取最…

unaipp打包app启动界面配置

1、配置代码 2、IOS端启动界面demo参考 iOS平台自定义storyboard启动界面 - DCloud问答

面试官当面夸奖了我,反手却把我挂了,这是什么套路?

最近几个朋友找我聊天&#xff0c;给我讲述了面试过程中遇到的一些不太理解的事情。我有个朋友作为一个技术面试官&#xff0c;今天来分享 10 个面试相关的套路。 1.自我介绍 自我介绍是一个重要的开始&#xff0c;好的开始是成功的一半。不需要太多花里胡哨的东西&#xff0…

SpringBoot05:自动配置原理

一、自动配置原理 SpringBoot官网 1、分析自动配置原理 以HttpEncodingAutoConfiguration&#xff08;Http编码自动配置&#xff09;为例解释自动配置原理 //表示这是一个配置类&#xff0c;和以前编写的配置文件一样&#xff0c;也可以给容器中添加组件 Configuration(prox…

解决阿里qiankun微应用资源无法加载

公司老项目多了&#xff0c;却想用新版本的框架&#xff0c;最好的解决办法就是用微前端。 本文说下我们在用阿里微前端框架qiankun&#xff0c;遇到的一些问题&#xff0c;以及一些巧妙的解决办法。 背景 因为接入微前端很长时间了&#xff0c;导致现在的微应用变成了实际意…

Python接口自动化测试之UnitTest详解

基本概念 UnitTest单元测试框架是受到JUnit的启发&#xff0c;与其他语言中的主流单元测试框架有着相似的风格。其支持测试自动化&#xff0c;配置共享和关机代码测试。支持将测试样例聚合到测试集中&#xff0c;并将测试与报告框架独立。 它分为四个部分test fixture、TestC…

【LeetCode】149. 直线上最多的点数

149. 直线上最多的点数&#xff08;困难&#xff09; 枚举直线 哈希表统计 思路 遍历每两个点之间的连线&#xff0c;然后计算这条连线上有多少个点。 具体步骤如下&#xff1a; 初始化最大点数为 0。遍历每个点&#xff0c;用它和其他点计算斜率。如果两个点的x坐标相同&…

7月大概率加息25bp!美股螺旋式下跌,加密市场“迎难而上”!

今年6月&#xff0c;美股标普500指数走出了自1948年以来最长的熊市&#xff0c;进入新的牛市&#xff0c;美联储暂停加息给全球资本市场一个喘息的机会。尽管如此&#xff0c;美国目前经济基本面的情况仍不及预期&#xff0c;股市其上涨态势恐怕将会迎来一轮调整。 以Solita Ma…

资深开发竟然不清楚int(1)和int(10)的区别

一、困惑 最近遇到个问题&#xff0c;有个表的要加个user_id字段&#xff0c;user_id字段可能很大&#xff0c;于是我提mysql工单alter table xxx ADD user_id int(1)。领导看到我的sql工单&#xff0c;于是说&#xff1a;这int(1)怕是不够用吧&#xff0c;接下来是一通解释。…