SpringCloud 运用(2)—— 跨服务调度

上一篇:SpringCloud 入门(1)—— nacos 注册中心-CSDN博客


1.RestTemplate 跨服务请求

RestTemplate 是 Spring 框架中的一个同步客户端,用于与 HTTP 服务进行交互。它简化了与 HTTP 服务器通信的过程,并且提供了对多种 HTTP 方法(如 GET、POST、PUT、DELETE 等)的支持,用于发送跨服务请求。

  <!--负载均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

 1.1 配置Bean

在 Spring Boot 2.0 及以上版本中,RestTemplate 不再自动配置,因此需要自己创建 RestTemplate Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;@Configuration
public class RemoteCallConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}

 1.2 构造函数注入RestTemplate

spring不推荐使用@AutoWired注解,进行自动注入。我们可以自己书写构造函数注入

public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {private  RestTemplate restTemplate;public CartServiceImpl(RestTemplate restTemplate) {this.restTemplate = restTemplate;}
}

 也可以通过lombok注解,自动生成构造函数,进行注入

 @AllArgsConstructor全参构造注解,但使用该注解可能导致一些不需要通过构造传参的变量,也会生成构造函数

@RequiredArgsConstructor注解,只有通过final修饰值,才会生成构造函数。 因为通过final修饰后,必需在定义时进行赋初始值,或者通过构造函数初始化

@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {private final RestTemplate restTemplate;
}

1.3 RestTemplate的使用

ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://localhost:8081/items?ids={ids}",//请求路径HttpMethod.GET,//请求方式null,//请求实体new ParameterizedTypeReference<List<ItemDTO>>() { },//返回值类型List<ItemDTO>Map.of("ids", CollUtil.join(itemIds, ","))//请求参数, 
);
//CollUtil.join(itemIds, ",")将集合转换成字符串,用逗号分隔。即集合123转化为字符串1,2,3。
​​​​​​​//Map.of() "ids"是键,字符串1,2,3是值

 我们可以看到http://localhost:8081/items中存在硬编码,这里我们可以使用上一篇学习到的nacos服务注册中心,将该微服务注册到nacos中,然后通过服务名发送请求。

当你通过 RestTemplate 发起请求时,Spring Cloud 提供了客户端负载均衡机制来决定具体发送到哪台计算机。默认的负载均衡策略是轮询(Round Robin)

这样如果该微服务在多台计算机都进行部署,并在nacos注册后,就可以实现负载均衡了

nacos注册中心地址教程:SpringCloud 入门(1)—— nacos 注册中心-CSDN博客

注册中心搭建完成后,使用构造函数将注入

@RequiredArgsConstructor
public class CartServiceImpl extends ServiceImpl<CartMapper, Cart> implements ICartService {private final RestTemplate restTemplate;private  final DiscoveryClient discoveryClient;//注册中心
}

 默认情况下,采用轮询的方式进行负载均衡

// 发起请求时,直接使用服务名称
ResponseEntity<List<ItemDTO>> response = restTemplate.exchange("http://item-service/items?ids={ids}", // 使用服务名称而不是具体实例 URIHttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ","))
);

 指定服务实例方式为随机

 // 查找 item-service 服务的实例列表List<ServiceInstance> instances = discoveryClient.getInstances("item-service");if (instances.isEmpty()) {throw new RuntimeException("No instances available for item-service");}// 随机选择一个服务实例Random random = new Random();ServiceInstance instance = instances.get(random.nextInt(instances.size()));// 发起请求,查询商品ResponseEntity<List<ItemDTO>> response = restTemplate.exchange(instance.getUri() + "/items?ids={ids}",HttpMethod.GET,null,new ParameterizedTypeReference<List<ItemDTO>>() {},Map.of("ids", CollUtil.join(itemIds, ",")));

利用Nacos实现了服务的治理,利用RestTemplate实现了服务的远程调用。但是远程调用的代码太复杂了,下面介绍一款更简单的方法OpenFeign。

2.OpenFeign 跨服务请求

OpenFeign 是一个声明式的 Web 服务客户端,它使得编写 HTTP 客户端变得更加简单。它是 Netflix Feign 的增强版本,并且与 Spring Cloud 深度集成,允许开发者通过创建接口并用注解描述 HTTP 请求来定义和使用 RESTful 客户端。这简化了代码的编写,因为你不需要构建 URL、手动解析 JSON 或处理其他繁琐的任务,对跨服务请求进行简化了。

2.1 设计思路

为了避免重复编码,下面有两种抽取思路:

  • 思路1:抽取到微服务之外的公共module(适用与聚合工程)

  • 思路2:每个微服务自己抽取一个module

如图:

方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。(适用于maven聚合模块中使用)

方案2抽取相对麻烦,工程结构相对更复杂,但服务之间耦合度降低。

 下面我们采用第一个思路,新建一名模板api模板,单独存放openFeign请求

 2.2 导入依赖

  <!--openFeign--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency><!--负载均衡器--><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-loadbalancer</artifactId></dependency>

2.3 编写Feign客户端

import com.heima.cart.domain.dto.ItemDTO;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestParam;import java.util.Collection;
import java.util.List;@FeignClient("item-service") //远程请求的服务
public interface ItemClient {@GetMapping("/items")//请求的服务路径List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

 2.4 启动OpenFeign功能

在需要发送跨服务请求(即:需要用到openFeign功能模块)的微服务的pom.xml中添加hm-api模块,

在启动类上添加注解@EnableFeignClients,开启openFeign功能 ,并且指明所在客户端的位置(类)

  • 方式1:声明扫描包:

  • 方式2:声明要用的API客户端

  将客户端注入,发起请求

 //注入private final ItemClient itemClient;//发起请求
List<ItemDTO> items = itemClient.queryItemByIds(itemIds);

2.5 openFeign日志

默认情况下,openFeign请求中,后台是没有日志的,一旦出错,很难发现。

需要手动创建config包,配置日志类

import feign.Logger;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfig {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.FULL;}
}

 在启动类中,开启日志,

全局生效:在@EnableFeignClients中配置,针对所有FeignClient生效。

@EnableFeignClients(defaultConfiguration = DefaultFeignConfig.class)

2.6 openFeign请求头

利用openFeign发送请求时,需要携带当前发起请求的用户信息。

这里我们将用户id放到请求头中,转发给另一个微服务。前端对后端发起的请求,交给网关处理,网关负责对jwt进行解析验证。网关验证完成后,才会转交给其他微服务。

后续更新网关处理方案.....

import com.hmall.common.utils.UserContext;
import feign.Logger;
import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Bean;public class DefaultFeignConfig {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.FULL;}@Beanpublic RequestInterceptor userInfoRequestInterceptor(){return new RequestInterceptor() {@Overridepublic void apply(RequestTemplate template) {// 获取登录用户Long userId = UserContext.getUser();if(userId == null) {// 如果为空则直接跳过return;}// 如果不为空则放入请求头中,传递给下游微服务template.header("user-info", userId.toString());}};}
}

2.7 openFeign连接池

Feign底层发起http请求,依赖于其它的框架。其底层支持的http客户端实现

  • HttpURLConnection:默认实现,不支持连接池

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

因此我们通常会使用带有连接池的客户端来代替默认的HttpURLConnection。比如,我们使用OK Http.

导入OKHttp依赖

<!--OK http 的依赖 -->
<dependency><groupId>io.github.openfeign</groupId><artifactId>feign-okhttp</artifactId>
</dependency>

application.yml配置文件中开启Feign的连接池功能,重启服务,连接池就生效了。

feign:okhttp:enabled: true # 开启OKHttp功能

下一篇

SpringCloud 入门(3)—— Nacos配置中心-CSDN博客

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

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

相关文章

解决Springboot整合Shiro自定义SessionDAO+Redis管理会话,登录后不跳转首页

解决Springboot整合Shiro自定义SessionDAORedis管理会话&#xff0c;登录后不跳转首页 问题发现问题解决 问题发现 在Shiro框架中&#xff0c;SessionDAO的默认实现是MemorySessionDAO。它内部维护了一个ConcurrentMap来保存session数据&#xff0c;即将session数据缓存在内存…

windows nmake 安装openssl

windows nmake 编译和安装 openssl 本文提供了在Windows环境下安装OpenSSL的详细步骤&#xff0c;包括下载Perl、NASM和VisualStudio&#xff0c;配置环境变量&#xff0c;使用PerlConfigure设置平台&#xff0c;通过nmake进行编译、测试和安装。整个过程涉及32位和64位版本的选…

一、Hadoop概述

文章目录 一、Hadoop是什么二、Hadoop发展历史三、Hadoop三大发行版本1. Apache Hadoop2. Cloudera Hadoop3. Hortonworks Hadoop四、Hadoop优势1. 高可靠性2. 高扩展性3. 高效性4. 高容错性五、Hadoop 组成1. Hadoop1.x、2.x、3.x区别2. HDFS 架构概述3. YARN 架构概述4. MapR…

python版本的Selenium的下载及chrome环境搭建和简单使用

针对Python版本的Selenium下载及Chrome环境搭建和使用&#xff0c;以下将详细阐述具体步骤&#xff1a; 一、Python版本的Selenium下载 安装Python环境&#xff1a; 确保系统上已经安装了Python 3.8及以上版本。可以从[Python官方网站]下载并安装最新版本的Python&#xff0c;…

vue---- H5页面 pdf,docx,excel文件预览下载功能

vue---- H5页面 pdf&#xff0c;docx&#xff0c;excel文件预览&&下载功能 pdf&#xff0c;docx&#xff0c;excel文件预览&&下载适用于vue2和vue3&#xff0c;示例为vue3 1.npm下载这些文件的插件&#xff08;选择自己需要预览的进行下载&#xff09; 安装pd…

vue3和springboot使用websocket通信

前端端口&#xff1a;9090 后端端口&#xff1a;8080 vue3 引入依赖&#xff1a; npm install sockjs-client stomp/stompjs vue页面 <template><div><h1>WebSocket 示例</h1><button click"sendMessage">发送消息</button>…

【时时三省】(C语言基础)动态内存函数malloc

山不在高&#xff0c;有仙则名。水不在深&#xff0c;有龙则灵。 ----CSDN 时时三省 malloc 开辟内存块 使用格式 void *malloc&#xff08;size_t sie&#xff09;&#xff1b; 示例 10*sizeof(int&#xff09;就是开辟空间的大小 如果p是void指针的话 p不能解引用 m…

选煤厂可视化技术助力智能化运营

通过图扑 HT 可视化搭建智慧选煤厂管理平台&#xff0c;优化了选煤生产流程&#xff0c;提高了资源利用率和安全性&#xff0c;助力企业实现智能化运营和可持续发展目标。

【论文笔记】Visual Alignment Pre-training for Sign Language Translation

&#x1f34e;个人主页&#xff1a;小嗷犬的个人主页 &#x1f34a;个人网站&#xff1a;小嗷犬的技术小站 &#x1f96d;个人信条&#xff1a;为天地立心&#xff0c;为生民立命&#xff0c;为往圣继绝学&#xff0c;为万世开太平。 基本信息 标题: Visual Alignment Pre-tra…

深入浅出 MyBatis | CRUD 操作、配置解析

3、CRUD 3.1 namespace namespace 中的包名要和 Dao/Mapper 接口的包名一致&#xff01; 比如将 UserDao 改名为 UserMapper 运行发现抱错&#xff0c;这是因为 UserMapper.xml 中没有同步更改 namespace 成功运行 给出 UserMapper 中的所有接口&#xff0c;接下来一一对…

前端:改变鼠标点击物体的颜色

需求&#xff1a; 需要改变图片中某一物体的颜色&#xff0c;该物体是纯色&#xff1b; 鼠标点击哪个物体&#xff0c;哪个物体的颜色变为指定的颜色&#xff0c;利用canvas实现。 演示案例 代码Demo <!DOCTYPE html> <html lang"en"><head>&l…

递归算法常见问题(Java)

问题&#xff1a;斐波那契数列,第1项和第2项都为1&#xff0c;后面每一项都为相邻的前俩项的和,求第n个数 解法&#xff1a;每一个数都为前俩个数之和&#xff0c;第1项和第2项都为1&#xff0c;所以写 方法f1(n)即为求第n个数&#xff0c;那么f1(n-1)为求第n-1个数&#xff0…

C项目 天天酷跑(下篇)

上篇再博客里面有&#xff0c;接下来我们实现我们剩下要实现的功能 文章目录 碰撞检测 血条的实现 积分计数器 前言 我们现在要继续优化我们的程序才可以使这个程序更加的全面 碰撞的检测 定义全局变量 实现全局变量 void checkHit() {for (int i 0; i < OBSTACLE_C…

论文解读——掌纹生成网络 RPG-Palm升级版PCE-Palm

该文章是2023年论文RPG-Palm的升级版 论文&#xff1a;PCE-Palm: Palm Crease Energy Based Two-Stage Realistic Pseudo-Palmprint Generation 作者&#xff1a;Jin, Jianlong and Shen, Lei and Zhang, Ruixin and Zhao, Chenglong and Jin, Ge and Zhang, Jingyun and Ding,…

oscp学习之路,Kioptix Level2靶场通关教程

oscp学习之路&#xff0c;Kioptix Level2靶场通关教程 靶场下载&#xff1a;Kioptrix Level 2.zip 链接: https://pan.baidu.com/s/1gxVRhrzLW1oI_MhcfWPn0w?pwd1111 提取码: 1111 搭建好靶场之后输入ip a看一下攻击机的IP。 确定好本机IP后&#xff0c;使用nmap扫描网段&…

第二十六周机器学习笔记:PINN求正反解求PDE文献阅读——正问题

第二十六周周报 摘要Abstract文献阅读《Physics-informed neural networks: A deep learning framework for solving forward and inverse problems involving nonlinear partial differential equations》1. 引言2. 问题的设置3.偏微分方程的数据驱动解3.1 连续时间模型3.1.1 …

【安全编码】Web平台如何设计防止重放攻击

我们先来做一道关于防重放的题&#xff0c;答案在文末 防止重放攻击最有效的方法是&#xff08; &#xff09;。 A.对用户密码进行加密存储使用 B.使用一次一密的加密方式 C.强制用户经常修改用户密码 D.强制用户设置复杂度高的密码 如果这道题目自己拿不准&#xff0c;或者…

中关村科金智能客服机器人如何解决客户个性化需求与标准化服务之间的矛盾?

客户服务的个性化和标准化之间的矛盾一直是一个挑战。一方面&#xff0c;企业需要提供标准化的服务以保持运营效率和成本控制&#xff1b;另一方面&#xff0c;为了提升客户满意度和忠诚度&#xff0c;企业又必须满足客户的个性化需求。为此&#xff0c;中关村科金推出了智能客…

Agent 案例分析:金融场景中的智能体-蚂蚁金服案例(10/30)

Agent 案例分析&#xff1a;金融场景中的智能体 —蚂蚁金服案例 一、引言 在当今数字化时代&#xff0c;金融行业正经历着深刻的变革。随着人工智能技术的飞速发展&#xff0c;智能体&#xff08;Agent&#xff09;在金融场景中的应用越来越广泛。蚂蚁金服作为金融科技领域的…

STM32F407 | Embedded IDE01 - vscode搭建Embedded IDE开发环境(支持JLINK、STLINK、DAPLINK)

导言 Embedded IDE官网:https://em-ide.com/docs/intro 我猜肯定有部分人使用SI Keil开发STM32项目&#xff0c;也有vscode Keil开发STM32程序。SI或vscode编写代码&#xff0c;然后切换Keil编译、下载、调试程序。有一段时间&#xff0c;我也是这么干的。但是&#xff0c;程…