微服务 OpenFeign 解析部署使用全流程

ops/2024/12/22 1:47:18/

目录

OpenFeign-toc" style="margin-left:0px;">1、什么是OpenFeign

1、Feign是什么??http请求

OpenFeign%E6%98%AF%E4%BB%80%E4%B9%88-toc" style="margin-left:40px;">2、OpenFeign是什么

3、Feign和openFeign有什么区别

2、应用

1、 需要开启nacos 和redis

2、准备工作

【1.对springsession做改动】

【2.对springsession-1做改动】

3、实现http请求管理

4、添加请求头

1、验证一下

2、实现一下 添加拦截器

5、参数传递


OpenFeign" style="background-color:transparent;">1、什么是OpenFeign

1、Feign是什么??http请求

Feign是集成了负载均衡、熔断机制、Http请求管理等功能的框架,作用是做微服务通信。Feign目前已经停止维护了,被Spring的OpenFeign接替实现后续功能。

负载均衡:服务器承担的压力就是负载,压力越大负载越大;均衡就是降低服务器承担的压力。

熔断机制:微服务之间通信的时候,A微服务给B微服务发送请求来获得B微服务里的数据。如果B微服务处于宕机状态,这样当A给B发请 求的时候,A会一直处于等待状态,等待B给出响应。这样对客户来说就不友好了。 熔断机制就是A给B发请求,过了一会没有 响应,于是A就自动切断了这一次请求,马上给客户一个响应。【熔断后面会详细学习,今天不做过多解释。】

http请求管理:就是A 的Controller 给 B 的Controller 发送了一个Http请求。

OpenFeign%E6%98%AF%E4%BB%80%E4%B9%88" style="background-color:transparent;">2、OpenFeign是什么

OpenFeign是SpringCloud下的一个框架,用于做微服务通信的,采用RESTFull风格做服务直接通信。实现方式也是通过发送http请求进行通信的,但是OpenFeign是在Spring环境下实现的,天然支持Spring的思想和注解,让开发变得更简单。

3、Feign和openFeign有什么区别

Feign对HTTP进行了封装,实现的微服务通信,OpenFeign是在Spring环境下对Feign进行的二次升级,让OpenFeign框架更简单,更贴近Spring,开发者在使用时减少了很多障碍。

官方文档: Spring Cloud OpenFeign

2、应用

1、 需要开启nacos 和redis

2、准备工作

【0.使用SpringSession共享例子】

下面图片是微服务SpringSession解析部署使用全流程-CSDN博客中创建出来的

在此基础上做改动。具体可了解此地址博客

改动后

【1.对springsession做改动】

#1.添加实体类 Score

package com.jr.entry;import lombok.Data;@Data
public class Score {private String name;private Double score;
}

#2.添加实体类 UserDto

package com.jr.entry;import lombok.Data;import java.util.List;@Data
public class UserDto {private String id;private String name;private String password;private List<Score> scoreList;
}

#3.添加接口 IUserService

package com.jr.servie;import com.jr.entry.UserDto;public interface IUserService {public UserDto info();
}

#4.添加接口实现类 UserServiceImpl

package com.jr.servie.impl;
import com.jr.entry.UserDto;
import com.jr.servie.IUserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements IUserService {@Overridepublic UserDto info() {return new UserDto();}
}

#5.添加 UserController 类

报红等后面的工具类配置完在引包

package com.jr.controller;
import com.jr.entry.UserDto;
import com.jr.servie.IUserService;
import com.jr.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;@RestController
@RequestMapping("/user")
public class UserController {@Autowiredprivate IUserService userService;@GetMappingpublic Result info(){UserDto userDto=userService.info();return Result.ok().put("data",userDto);}
}

#6.添加枚举 ResultCode

package com.jr.util;public enum ResultCode {SUCCESS(0, "请求成功"),ERROR(1, "请求失败"),;private int code;private String message;ResultCode(int code, String message) {this.code = code;this.message = message;}public int getCode() {return code;}public String getMessage() {return message;}
}

#7.添加工具类 Result

package com.jr.util;import lombok.Data;import java.util.HashMap;
import java.util.Map;@Data
public class Result {private Integer code;private String message;private Map<String, Object> map = new HashMap<>();private Result() {}public static Result ok() {Result r = new Result();r.setCode(ResultCode.SUCCESS.getCode());r.setMessage(ResultCode.SUCCESS.getMessage());return r;}public static Result error() {Result r = new Result();r.setCode(ResultCode.ERROR.getCode());r.setMessage(ResultCode.ERROR.getMessage());return r;}public Result put(String key, Object value) {map.put(key, value);return this;}public Object get(String key) {return map.get(key);}}

#8.修改application.properties文件中,项目注册名字:

spring.application.name=openfeignDemo1

【2.对springsession-1做改动】

实体类是相同的,可以将上一个粘贴过来

#1.添加实体类 Score

package com.jr.entry;import lombok.Data;@Data
public class Score {private String name;private Double score;
}

#2.添加实体类 UserDto

package com.jr.entry;import lombok.Data;import java.util.List;@Data
public class UserDto {private String id;private String name;private String password;private List<Score> scoreList;
}

#3.添加接口ScoreService

package com.jr.service;import com.jr.entry.Score;import java.util.List;public interface ScoreService {public List<Score> info();
}

#4.添加接口实现类 ScoreServiceImpl

package com.jr.service.impl;
import com.jr.entry.Score;
import com.jr.service.ScoreService;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;@Service
public class ScoreServiceImpl implements ScoreService {@Overridepublic List<Score> info() {List<Score> result = new ArrayList<>();for (int i=0;i<3;i++){Score score=new Score();score.setName("name"+i);score.setScore(Math.random()*10);result.add(score);}return result;}
}

#5.添加 ScoreController 类

报红等后面工具类配置完在引入包

package com.jr.controller;
import com.jr.entry.Score;
import com.jr.service.ScoreService;
import com.jr.util.Result;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;import java.util.List;@RestController
@RequestMapping("/score")
public class ScoreController {@Autowiredprivate ScoreService scoreService;@GetMapping("/info")public Result info(){List<Score> list=scoreService.info();return Result.ok().put("list",list);}
}

#6.添加枚举 ResultCode

package com.jr.util;public enum ResultCode {SUCCESS(0, "请求成功"),ERROR(1, "请求失败"),;private int code;private String message;ResultCode(int code, String message) {this.code = code;this.message = message;}public int getCode() {return code;}public String getMessage() {return message;}
}

#7.添加工具类 Result

package com.jr.util;import lombok.Data;import java.util.HashMap;
import java.util.Map;@Data
public class Result {private Integer code;private String message;private Map<String, Object> map = new HashMap<>();private Result() {}public static Result ok() {Result r = new Result();r.setCode(ResultCode.SUCCESS.getCode());r.setMessage(ResultCode.SUCCESS.getMessage());return r;}public static Result error() {Result r = new Result();r.setCode(ResultCode.ERROR.getCode());r.setMessage(ResultCode.ERROR.getMessage());return r;}public Result put(String key, Object value) {map.put(key, value);return this;}public Object get(String key) {return map.get(key);}}

#8.修改application.properties文件中,项目注册名字:

spring.application.name=openfeignDemo2

#9.启动项目,访问:

现在两个项目都可以单独访问,想要访问到用户信息后同时访问到成绩如下

3、实现http请求管理

【1.添加open Feign依赖】

两个项目均添加

    <!-- feign --><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>

【2.在 “用户项目” 里,添加一个接口】

package com.jr.feign;
import com.jr.util.Result;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.stereotype.Component;
import org.springframework.web.bind.annotation.GetMapping;/*** openfeignDemo2是springsession-1在nacos注册的项目名()*/
@FeignClient("openfeignDemo2")
@Component
public interface ScoreFeign {/*** @GetMapping("/score/info")里面是springsession-1的路由下面是方法* @return*/@GetMapping("/score/info")public Result info();
}

定义了Feign接口,接口中的方法和对应服务端Controller方法一样,两点不同

  • RequestMapping注解的值要求全路径,包括controller上和方法上的注解地址拼接到一起

  • 添加FeignClient注解,参数是服务端微服务的名称

【3.改动UserServiceImpl实现类】

原来的代码

package com.jr.servie.impl;
import com.jr.entry.UserDto;
import com.jr.servie.IUserService;
import org.springframework.stereotype.Service;@Service
public class UserServiceImpl implements IUserService {@Overridepublic UserDto info() {return new UserDto();}
}

现在的代码

package com.jr.servie.impl;
import com.jr.entry.Score;
import com.jr.entry.UserDto;import com.jr.feign.ScoreFeign;
import com.jr.servie.IUserService;
import com.jr.util.Result;
import com.jr.util.ResultCode;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;import java.util.List;@Service
public class UserServiceImpl implements IUserService {@Autowiredprivate ScoreFeign scoreFeign;@Overridepublic UserDto info() {UserDto userDto=new UserDto();userDto.setId("10");userDto.setName("zhangsan");userDto.setPassword("123456");Result result=scoreFeign.info();if(result.getCode() == ResultCode.SUCCESS.getCode()){userDto.setScoreList((List<Score>) result.get("list"));}return userDto;}
}

【4.启动类添加注解 @EnableFeignClients】

启动项目

4、添加请求头

OpenFeign发送请求时,对方服务接收不到请求里的header信息,而header中的数据一般在其他微服务中也很重要,所以要添加进去。

1、验证一下

修改一下user项目控制器方法,添加了请求头的获得。

引入的包是这个
import org.apache.catalina.servlet4preview.http.HttpServletRequest;
 @GetMappingpublic Result info(HttpServletRequest request){String test = request.getHeader("test");System.out.println("user项目header"+test);UserDto userDto=userService.info();return Result.ok().put("data",userDto);}

修改一下score项目控制器方法,添加了请求头的获得。

引入的包是这个
import org.apache.catalina.servlet4preview.http.HttpServletRequest;

 @GetMapping("/info")public Result info(HttpServletRequest request){String test = request.getHeader("test");System.out.println("Score项目的head"+test);List<Score> list=scoreService.info();return Result.ok().put("list",list);}

postman 发送请求,查看控制台结果:

2、实现一下 添加拦截器

在user项目里,添加com.jr.interceptor.RequestHeaderInterceptor过滤器:

package com.jr.interceptor;import feign.RequestInterceptor;
import feign.RequestTemplate;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.context.request.RequestAttributes;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;import javax.servlet.http.HttpServletRequest;@Configuration
public class RequestHeaderInterceptor implements RequestInterceptor {@Overridepublic void apply(RequestTemplate template) {RequestAttributes requestAttributes = RequestContextHolder.getRequestAttributes();if (requestAttributes == null) {return;}HttpServletRequest request = ((ServletRequestAttributes) requestAttributes).getRequest();String test = request.getHeader("test");template.header("test", test);}
}

5、参数传递

1、controller代码: 在user项目下的UserController里,添加如下代码。

   @GetMapping("/{id}")public Result id(@PathVariable String id) {  //url传值UserDto userDto = userService.id(id);return Result.ok().put("data", userDto);}
@PostMapping("/add")public Result add(@RequestBody UserDto user) { //对象传值UserDto userDto = userService.add(user);return Result.ok().put("data", userDto);}

2、对应的接口,添加两个方法:

3、对应的接口实现类,重写两个方法:

 @Overridepublic UserDto add(UserDto user) {UserDto userDto=new UserDto();Result result=scoreFeign.add(user);if(result.getCode() == ResultCode.SUCCESS.getCode()){UserDto resultUser= JSON.parseObject(JSON.toJSONString(result.get("data")),UserDto.class);System.out.println(resultUser);BeanUtils.copyProperties(resultUser,userDto);}return userDto;}@Overridepublic UserDto id(String id) {UserDto userDto=new UserDto();Result result=scoreFeign.id(id);if(result.getCode() == ResultCode.SUCCESS.getCode()){userDto.setId((String)result.get("id"));}return userDto;}

4.controller代码: 在score项目下的ScoreController里,添加如下代码。

 @GetMapping("/{id}")public Result id(@PathVariable String id) {return Result.ok().put("id", id);}@PostMapping("/add")public Result add(@RequestBody UserDto user) {return Result.ok().put("data", user);}

5.feign接口, 在user项目下的ScoreFeign接口里,添加如下代码。

 @GetMapping("/score/{id}")Result id(@PathVariable String id);@PostMapping("/score/add")Result add(@RequestBody UserDto user);

6.测试一下,查看结果:


http://www.ppmy.cn/ops/119670.html

相关文章

华为设备所有查看命令以及其对应作用

display interface&#xff1a;查看接口的状态、配置和统计信息。display ip interface brief&#xff1a;简要查看接口的 IP 地址信息。display ip routing-table&#xff1a;查看路由表信息。display ospf peer&#xff1a;查看 OSPF 邻居的状态。display ospf routing&#…

【C++笔记】八、结构体 [ 4 ]

8.7 结构体中 const使用场景 作用&#xff1a;用 const 来防止误操作 #define _CRT_SECURE_NO_WARNINGS 1 #include<iostream>; using namespace std; #include<string>//const的使用场景struct student {//姓名string name;//年龄int age;int score;};//将函数中…

自动驾驶电车难题的康德式道德决策

摘 要 自动驾驶电车难题是检验人工智能伦理可行性的一块试金石 , 面对不同情境 , 其计算程序既要作出可决定的、 内在一致的判断决策 , 又要与人类的普遍道德常识相兼容 。 康德义务论给出了具有普遍性与一致性的理论框架。 自动驾驶电车的道德决策可视为由计算程序执行的第…

前端DOM常用操作

前端DOM常用操作及代码案例 在前端开发中&#xff0c;DOM&#xff08;文档对象模型&#xff09;操作是不可或缺的一部分。通过DOM&#xff0c;开发者可以查找节点、增删节点、修改节点内容、操作CSS样式等。本文将介绍一些常用的DOM操作&#xff0c;并提供相应的代码案例。 一…

微软Active Directory:组织身份与访问管理的基石

目录 摘要 1. 引言 2. Active Directory的基本概念 2.1 目录服务的定义 2.2 Active Directory的历史 3. Active Directory的架构 3.1 域(Domain) 3.2 树(Tree) 3.3 森林(Forest) 3.4 组织单位(Organizational Unit, OU) 3.5 目录信息树(Directory Informati…

Qt 智能指针

Qt 中智能指针包括&#xff1a; QSharedPointer ----> std::shared_ptr 引用计数 多个线程同时修改 QSharedPointer 指向的数据时还要应该考虑 加锁 QScopedPointer ----> std::uniq_ptr 独占QScopedArrayPointerQWeakPointer ----> std::weak_ptr 弱引用计数QPointe…

git 基本原理

文章内容来源于视频 举个案例&#xff0c;家族里面有一本记载祖传秘籍的菊花宝典&#xff0c;这本菊花宝典的正本存储在家族祠堂里面&#xff0c;每一个家庭从正本复制一本存在自己家中&#xff0c;称为副本。这个过程称为clone 一个家庭需要再菊花宝典中添加技能&#xff0c…

vscode 的terminal 输出打印行数限制设置

修改 VSCODE 的 settings.json文件 "terminal.integrated.scrollback": 100000, {"extensions.ignoreRecommendations": true,"workbench.colorTheme": "Monokai","explorer.confirmDelete": false,"editor.fontSize…