微服务(三)——远程调用

news2024/11/25 16:26:42

目录

  • 前言
  • 1. RestTemplate
    • 1. 导入依赖
    • 2. 代码
    • 3. 常用方法
  • 2. jodd-http
    • 1. 引入依赖
    • 2. 代码
    • 3. 测试
  • 3. Feign
    • 1. 引入依赖
    • 2. 使用过程
    • 3. 自定义配置
    • 4. 优化


前言

微服务都是独立部署的,要实现一个业务可能需要多个服务之间的通信,所以远程调用必不可少,本文将提供三种远程调用的方案:jodd-httpRestTemplateFeign

在此说一下 springboot父子 工程的搭建流程:

  • 先创建一个springboot项目,然后删掉不必要的文件,如下图:

  • 然后创建子项目,新建模块,选择 maven 工程

注意:

  • 父工程中已经导入的依赖,子工程会集成,无需再次导入
  • 父工程可以用 <dependencyManagement> 来进行依赖版本管理,如下:
    当父工程规定好 spring-cloud 的版本号之后,子工程引入该依赖或其旗下依赖,都会根据父工程的版本号来引入
        <properties>
            <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
            <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
            <java.version>1.8</java.version>
            <spring.cloud-version>2021.0.5</spring.cloud-version>
        </properties>
    
        <dependencyManagement>
            <dependencies>
                <!--spring-cloud-->
                <dependency>
                    <groupId>org.springframework.cloud</groupId>
                    <artifactId>spring-cloud-dependencies</artifactId>
                    <version>${spring.cloud-version}</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
                <!--spring-cloud-alibaba-->
                <dependency>
                    <groupId>com.alibaba.cloud</groupId>
                    <artifactId>spring-cloud-alibaba-dependencies</artifactId>
                    <version>2.2.6.RELEASE</version>
                    <type>pom</type>
                    <scope>import</scope>
                </dependency>
            </dependencies>
        </dependencyManagement>
    

1. RestTemplate

前期准备:

  • 搭建好工程:

    remote_service 是模拟远程服务的一个模块,其 controller 代码如下:

    @RequestMapping("/remote")
    @RestController
    public class RemoteController {
        @GetMapping("/{name}")
        public String sayHello(@PathVariable("name") String name) {
            return name.toUpperCase() + " 发起了请求,并请求成功";
        }
    }
    

1. 导入依赖

RestTemplate 是spring自带的远程调用工具,所以只要有 spring 的依赖,都可以直接使用(随便导入一个 spring-boot-dependencies 或者 spring-boot-starter-web 都行)。

2. 代码

在使用 RestTemplate 之前,需要先在容器中注册。将下述代码写在一个配置类(@Configuration)中,或者直接写在 启动类(main)中都可以。

    @Bean
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }

controller 代码:

@RequestMapping("/rest")
@org.springframework.web.bind.annotation.RestController
public class RestController {
    private static final String NAME = "rest_template";

    @Autowired
    private RestTemplate restTemplate;

    @GetMapping
    public String sayHello() {
        String url = "http://127.0.0.1:8088/remote/" + NAME;
        String msg = restTemplate.getForObject(url, String.class);
        return msg;
    }
}

测试: 请求成功。

3. 常用方法

RestTemplate 的使用比较简单,这里再简单说一下它的常用方法:

方法请求说明
getForEntityGET常用:public <T> ResponseEntity<T> getForEntity(地址, 返回类型)
getForObjectGET常用:public <T> T getForObject(地址, 返回类型)
对getForEntity函数的进一步封装,只关注返回的消息体的内容,对其他信息都不关注
postForEntityPOST常用:public <T> ResponseEntity<T> postForEntity(地址, 上传的参数(可为空),返回类型)
postForObjectPOST常用:public <T> ResponseEntity<T> postForObject(地址, 上传的参数(可为空),返回类型)
对postForEntity函数的进一步封装,只关注返回的消息体的内容,对其他信息都不关注
postForLocationPOST常用:public URI postForLocation(地址, 上传的参数(可为空))
返回新资源所在的 url
putPUT常用:public void put(地址, 上传的参数(可为空))
deleteDELETE常用:public void delete(地址, 上传的参数)

在这里补充一下 RestfulHTTP动词

  • GET(SELECT):从服务器取出资源(一项或多项)
  • POST(CREATE):在服务器新建一个资源
  • PUT(UPDATE):在服务器更新资源(客户端提供改变后的完整资源)
  • PATCH(UPDATE):在服务器更新资源(客户端提供改变的属性)
  • DELETE(DELETE):从服务器删除资源

2. jodd-http

1. 引入依赖

需要导入两个依赖:

  • fastjson:用于 json 数据 与 接收类型 的转化
  • jodd-http:用于发起 http 请求
        <!-- fastjson -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>1.2.83</version>
        </dependency>
        <!-- jodd-http -->
        <dependency>
            <groupId>org.jodd</groupId>
            <artifactId>jodd-http</artifactId>
            <version>3.7.1</version>
        </dependency>

2. 代码

工具类:

import com.alibaba.fastjson.JSONObject;
import jodd.http.HttpRequest;
import jodd.http.HttpResponse;

import java.nio.charset.StandardCharsets;
import java.util.Map;

public class HttpUtil {

    public static String post(String url, Map<String, Object> map) {
        HttpResponse res = HttpRequest.post(url).connectionTimeout(90000).timeout(90000)
                .contentType("application/json", "UTF-8")
                .bodyText(JSONObject.toJSONString(map), "application/json", "UTF-8")
                .send();
        res.charset("utf-8");
        return res.bodyText();
    }

    public static String post(String url, String jsonStr) {
        HttpResponse resp = HttpRequest.post(url).connectionTimeout(60000).timeout(60000)
                .contentType("application/json", StandardCharsets.UTF_8.toString())
                .bodyText(jsonStr ,"application/json", "UTF-8")
                .send();
        resp.charset(StandardCharsets.UTF_8.toString());
        return resp.bodyText();
    }

    public static String get(String url, Map<String, String> params) {
        HttpRequest request = HttpRequest.get(url);
        if (params != null) {
            request.query(params);
        }
        HttpResponse response = request.send();
        return response.bodyText();
    }
}

Controller:

@RequestMapping("/jodd")
@RestController
public class JoddController {
    private static final String NAME = "jodd_http";

    @GetMapping
    public String sayHello() {
        String url = "http://127.0.0.1:8088/remote/" + NAME;
        String msg = HttpUtil.get(url, new HashMap<>());
        return msg;
    }
}

3. 测试

注意: 这个我在之前的文章中讲过,点击跳转 ,这里就不再多说。

3. Feign

Feign是一个声明式的http客户端:点击图片跳转。

鉴于前面的两种方法,对于参数复杂URL难以维护,所以建议使用 Feign

1. 引入依赖

Feign 是基于 springcloud 来发起远程请求的,需要与 nacos 等注册中心搭配使用,点击跳转注册中心文章。

要引入 Feign 依赖,就需要先引入 springcloud 的依赖:

        <!--spring-cloud-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-dependencies</artifactId>
            <version>2021.0.5</version>
            <type>pom</type>
            <scope>import</scope>
        </dependency>

注意: 引入 springcloud 依赖的时候,需要注意 springboot 的版本。

  • springboot 与 springcloud 的版本对应关系
    点击图片跳转

然后导入 Feign 依赖:

        <!--Feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
            <version>3.1.2</version>
        </dependency>

注意: 启动项目报错: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-loadbalancer?

解决方案: https://blog.csdn.net/qq_43788878/article/details/115764008

2. 使用过程

  1. 在启动类上添加一个 @EnableFeignClients

  2. 编写 Feign 接口

    @Component
    //@FeignClient:微服务客户端注解,value:指定微服务的名字,这样就可以使Feign客户端直接找到对应的微服务
    @FeignClient(value = "remote")
    public interface MyFeignClient {
    
        @GetMapping("/remote/{name}")
        String sayHello(@PathVariable("name") String name);
    }
    
    

    这个客户端主要是基于SpringMVC的注解来声明远程调用的信息,比如:

    • 服务名称:remote
    • 请求方式:GET
    • 请求路径:/remote/{name}
    • 请求参数:String name
    • 返回值类型:String

    这样,Feign就可以帮助我们发送http请求,无需自己使用RestTemplate来发送了。

  3. controller

    @RestController("/feign")
    public class FeignController {
        private static final String NAME = "feign";
    
        @Resource
        private MyFeignClient feignClient;
    
        @GetMapping
        public String sayHello() {
            String msg = feignClient.sayHello(NAME);
            return msg;
        }
    }
    

以上就是 Feign 的使用步骤,因为懒得去搭建注册中心,所以就不测试了。

3. 自定义配置

Feign可以支持很多的自定义配置,如下表所示:

类型作用说明
feign.Logger.Level修改日志级别包含四种不同的级别:NONE、BASIC、HEADERS、FULL
feign.codec.Decoder响应结果的解析器http远程调用的结果做解析,例如解析json字符串为java对象
feign.codec.Encoder请求参数编码将请求参数编码,便于通过http请求发送
feign. Contract支持的注解格式默认是SpringMVC的注解
feign. Retryer失败重试机制请求失败的重试机制,默认是没有,不过会使用Ribbon的重试

一般情况,直接使用默认配置就OK了。

自定义配置的方法:

  • 方法一:修改配置文件

    feign:  
      client:
        config: 
          remote: # 针对某个微服务的配置,这里也可以使用 default(全局配置),针对所有微服务
            loggerLevel: FULL #  日志级别 
    

    日志的四种级别:

    • NONE:不记录任何日志信息,这是默认值
    • BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
    • HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
    • FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据
  • 方式二:Java代码
    先声明一个类,然后声明一个Logger.Level的对象

    public class DefaultFeignConfiguration  {
        @Bean
        public Logger.Level feignLogLevel(){
            return Logger.Level.FULL; // 日志级别为BASIC
        }
    }
    

    启动类添加注解(全局配置,针对所有微服务):

    @EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
    

    添加到自定义 FeignClient 接口中(针对某一微服务):

    @FeignClient(value = "remote", configuration = DefaultFeignConfiguration .class)
    

4. 优化

  • 日志级别尽量用basic
  • 使用连接池,这是提高 Feign 性能的主要手段:
    Feign底层发起http请求,依赖于其它的框架。其底层客户端实现包括:
    • URLConnection:默认实现,不支持连接池

    • Apache HttpClient :支持连接池

    • OKHttp:支持连接池

优化演示:

  • 引入 feign-httpclient 依赖(带连接池的客户端)

    <dependency>
        <groupId>io.github.openfeign</groupId>
        <artifactId>feign-httpclient</artifactId>
    </dependency>
    
  • 配置连接池和日志

    feign:
      client:
        config:
          default: # default全局的配置
            loggerLevel: BASIC # 日志级别,BASIC就是基本的请求和响应信息
      httpclient:
        enabled: true # 开启feign对HttpClient的支持
        max-connections: 200 # 最大的连接数
        max-connections-per-route: 50 # 每个路径的最大连接数
    

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

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

相关文章

html标签分类及其他知识

1、标签按照类型可以划分为三种类型&#xff1a; block&#xff1a;div、p、ul、li、h1… 1、独占一行2、支持所有样式3、不写宽的时候&#xff0c;跟父元素的宽相同4、所占区域是一个矩形 inline&#xff1a;span、a、em、strong、img… 1、挨在一起2、有些样式不支持&#x…

编译原理——求后缀表达式、三元式、四元式

一、求后缀表达式 可能就是一填空题&#xff0c;考试应该也不会太复杂&#xff0c;要会&#xff0c;掌握着由外到内求解思想即可&#xff1b; 其实就是二叉树的后序遍历&#xff0c;左右根&#xff1b;拆分的顺序就是由左到右顺序进行&#xff0c;小括号内的最后拆&#xff0…

4线触摸屏控制器ET2046介绍

4线触摸屏控制器ET2046简介 ET2046是4线触摸屏控制器&#xff0c;支持1.5V&#xff5e;5.5V的低压I/O 接口。ET2046具有内置2.5V电压源&#xff0c;可用于辅助输入、电池监测和温度检测模式的测量。在不使用时&#xff0c;也可将内置电压源关闭以节约电力。内置电压源最低可工作…

JS 执行机制

1、JS 是单线程 JavaScript 语言的一大特点就是单线程&#xff0c;也就是说&#xff0c;同一个时间只能做一件事。这是因为 Javascript 这门脚本语言诞生的使命所致——JavaScript 是为处理页面中用户的交互&#xff0c;以及操作 DOM 而诞生的。比如我们对某个 DOM 元素进行添加…

建议使用这些方法来优化Mac,运行速度直线上升

Mac系统的稳定性和流畅性一直备受大家称赞&#xff0c;这也是大多数人选择Mac的原因&#xff0c;尽管如此&#xff0c;我们仍不时地对Mac进行优化、调整&#xff0c;以使其比以前更快、更流畅地运行。以下是小编分享给各位的Mac优化方法&#xff0c;记得保存哦~ 一、释放被过度…

Groovy安全高效的执行(死循环,休眠,危险方法)

背景 在很多场景下有需要执行异步任务&#xff0c;或者执行用户的自定义任务时&#xff0c;通常我们会使用Groovy脚本能力来完成任务。通过groovy动态脚本能力&#xff0c;在业务执行过程中动态执行不同业务线或者用户的脚本&#xff0c;来满足不同需求。 这样可以非常方便的进…

关于CSS选择器优先级的规则说明

简单规则&#xff1a; !important > 行内样式 > id选择器 > 类选择器 > 元素选择器 > 通配选择器 选择器举例说明&#xff1a; !important&#xff1a; <h1 id"title">好好学习&#xff0c;天天向上</h1> <style type"text/…

ArcGIS基础实验操作100例--实验1绘制自定义线、垂线、平行线

本实验专栏来自于汤国安教授《地理信息系统基础实验操作100例》一书 实验平台&#xff1a;ArcGIS 10.6 实验数据&#xff1a; 通过百度网盘分享的文件&#xff1a;地理信息系统基础实验100例 链接:https://pan.baidu.com/s/1sprJ2eyDAkYWiLwyuTIf1g 提取码:gb7y 复制这段内容…

Doris(一)

1、Doris简介 Doris是由百度大数据研发&#xff0c;是一个现代化的MPP&#xff08;Massively Parallel Processing&#xff09;大规模并行处理的分析型数据库产品。仅需亚秒级响应时间即可获得查询结果&#xff0c;有效地支持实时数据分析。 Apache Doris 的分布式架构非常简洁…

北上广深杭房价高压下,这也许是软件测试员扎根的唯一出路...

简单算一笔账&#xff0c;目前小公司软件测试员工资一般是1万出头&#xff0c;年薪普遍在20万以下。在不考虑通胀和工资增长的情况下&#xff0c;除去吃喝需要攒30年才能攒出一线城市房子的首付&#xff0c;以这样的收入水平&#xff0c;基本上没法扎根。 想拿高薪最好的途径就…

API文档、技术文档工具 - ShowDoc - 使用

1.应用场景 主要用于使用适合IT团队的 API文档、技术文档工具 进行项目文档书写以及进行开发。 2.学习/操作 1.文档阅读 ShowDoc ShowDoc - demo 安装/升级手册 GitHub - star7th/showdoc: ShowDoc is a tool greatly applicable for an IT team to share documents online一…

LeetCode Hot 100~Day3

目录 字母异位词分组 最大子数组和 跳跃游戏 合并区间 不同路径 最小路径和 爬楼梯 颜色分类 子集 单词搜索 二叉树的中序遍历 不同的二叉搜索树 字母异位词分组 题目链接&#xff1a;49. 字母异位词分组 示例 输入: strs ["eat", "tea&quo…

[DonkeyCar][树莓派]基础01 - 首次配置 - WIFI

2022年圣诞节到来啦&#xff0c;疫情把刚刚起来的工作似乎又慢了下来&#xff0c;在冲刺决赛圈的同时&#xff0c;也许开一个新的领域&#xff0c;写一个博客是比较好的方式。 一、前言 拿到树莓派开发板的时候&#xff0c;一般&#xff0c;供应商都会配合烧录的镜像。但是&am…

《图解TCP/IP》阅读笔记(第七章 7.6)—— BGP 边界网关协议

7.6 BGP BGP&#xff08;Border Gateway Protocol&#xff09;&#xff0c;边界网关协议&#xff0c;是用于连接不同组织机构&#xff08;或者说不同自治系统&#xff09;的一种协议&#xff0c;其属于EGP&#xff08;外部网关协议&#xff09;&#xff0c;我们在7.2节中了解过…

01)FastDFS文件服务器安装和测试可用性

FastDFS简介 ​ FastDFS是一个轻量级的开源分布式文件系统。2008年4月份开始启动。类似google FS的一个轻量级分布式文件系统,纯C实现,支持Linux、FreeBSD、AIX等UNIX系统。 ​ 主要解决了大容量的文件存储和高并发访问的问题,文件存取时实现了负载均衡。实现了软件方式的…

PicoRV32 笔记 06 压缩指令集

PicoRV32 中实现压缩指令集选项 COMPRESSED_ISA&#xff0c;当设置COMPRESSED_ISA1开启支持16位指令集。压缩指令有很多优点&#xff0c;当我们在FPGA中实现PicoRV32的时候&#xff0c;使用RISCV的C扩展能有效的增大代码密度&#xff0c;原本32位1条指令变为16位一条指令&#…

synchronized 和 ReentrantLock 的区别

&#x1f388;专栏链接:多线程相关知识详解 synchronized和ReentrantLock的 区别 缺点 优势 synchronized和ReentrantLock两者都是可重入锁 ReentrantLock的三个核心方法: Ⅰ.lock(加锁) Ⅱ.unlock(解锁) Ⅲ.tryLock(尝试加锁) import java.util.concurrent.locks.Reentrant…

Android并发编程里的线程原理

1.进程和线程的概念 抛开那些官方的概念&#xff0c;我们可以大致理解为:进程就是手机里运行的一个个应用&#xff0c;他们都是一个个的进程&#xff08;当然&#xff0c;有些App是多进程的&#xff0c;这个先不谈&#xff09;。线程则是进程中对应的一个任务的执行控制流。如果…

广播机制-案例

广播机制-案例 1.静态注册案例-接收开机广播 1.案例&#xff1a;接收开机的广播 创建自定义的BroadcastReceiver用于处理监听到的系统广播。//接收系统开机的广播事件 public class BootCompleteReceiver extends BroadcastReceiver {Overridepublic void onReceive(Context co…

2023跨境出海指南:马来西亚网红营销白皮书

当前的东南亚市场可谓是是企业出海的大热门&#xff0c;马来西亚作为东南亚地区的第三大经济体&#xff0c;其发展形势也是一片大好。疫情出现后&#xff0c;马来西亚的娱乐和消费转移到线上&#xff0c;对社媒的依赖也催发了网红经济的发展。本文Nox聚星就和大家探讨一下&…