当前位置: 首页 > article >正文

远程调用总结

远程调用的作用

  在原来的springboot项目中通常是通过调用业务层来实现一个功能。在微服务中由于我们将许多业务进行一个拆开,但是我们需要其他业务层的数据所以就需要通过发送请求的方式来获取数据

实现注册中心nacos(第一步)

我们基于Docker来部署Nacos的注册中心,首先我们要准备MySQL数据库表,用来存储Nacos的数据。由于是Docker部署,所以大家需要将资料中的SQL文件导入到你Docker中的MySQL容器中:

其中的nacos/custom.env文件中,有一个MYSQL_SERVICE_HOST也就是mysql地址,需要修改为你自己的虚拟机IP地址:

然后,将课前资料中的nacos目录上传至虚拟机的/root目录。

进入root目录,然后执行下面的docker命令:

docker run -d \
--name nacos \
--env-file ./nacos/custom.env \
-p 8848:8848 \
-p 9848:9848 \
-p 9849:9849 \
--restart=always \
nacos/nacos-server:v2.1.0-slim

值得注意的是:当我们电脑的ip地址改变的时候 需要通过将nacos从docker中进行移除,重新通过docker进行run,同时别忘忘记将nacos/custom.env中的ip进行修改

启动完成后,访问下面地址:http://192.168.150.101:8848/nacos/,注意将192.168.150.101替换为你自己的虚拟机IP地址。

首次访问会跳转到登录页,账号密码都是nacos

服务注册

将一个模块注册到nacos注册中心的步骤如下

1.引入依赖

2.配置nacos地址

添加依赖

在需要实现nacos的模块中的pom文件中添加一下依赖

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

 配置Nacos

在yml文件添加nacos的地址配置

spring:
  application:
    name: item-service # 服务名称
  cloud:
    nacos:
      server-addr: 192.168.150.101:8848 # nacos地址

然后我们访问 http:虚拟机地址:8848/nacos/

看是否可以登录进去,如果可以登录进去就代表成功

 服务发现

服务的消费者要去nacos订阅服务,这个过程就是服务发现,步骤如下:

  • 引入依赖

  • 配置Nacos地址

  • 发现并调用服务

引入依赖

服务发现除了要引入nacos依赖以外,由于还需要负载均衡,因此要引入SpringCloud提供的LoadBalancer依赖。

在消费者中模块中添加一下依赖

<!--nacos 服务注册发现-->
<dependency>
    <groupId>com.alibaba.cloud</groupId>
    <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>

这样消费者还有生产者都全部确定

OpenFegin(第二步)

快速使用

引入依赖

服务的pom.xml中引入OpenFeign的依赖和loadBalancer依赖:

  <!--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>

 启用OpenFegin

接下来,我们在cart-serviceCartApplication启动类上添加注解,启动OpenFeign功能:

"@EnableFeignClients" 这个注解就是气筒OpenFegin服务的注解

package com.hmall.cart;

import com.hmall.api.config.DefaultFeignConfig;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.openfeign.EnableFeignClients;

@EnableFeignClients(basePackages = "com.hmall.api.client",defaultConfiguration = DefaultFeignConfig.class)
@MapperScan("com.hmall.cart.mapper")
@SpringBootApplication
public class CartApplication {
    public static void main(String[] args) {
        SpringApplication.run(CartApplication.class, args);
    }
}

编写OpenFeign客户端

cart-service(这个服务是一个例子)中,定义一个新的接口,编写Feign客户端(现在是在cart包中,后面需要将统一写在api模块中):

其中代码如下:

package com.hmall.cart.client;

import com.hmall.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.List;

@FeignClient("item-service")
public interface ItemClient {

    @GetMapping("/items")
    List<ItemDTO> queryItemByIds(@RequestParam("ids") Collection<Long> ids);
}

这里只需要声明接口,无需实现方法。接口中的几个关键信息:

  • @FeignClient("item-service") :声明服务名称

  • @GetMapping :声明请求方式

  • @GetMapping("/items") :声明请求路径

  • @RequestParam("ids") Collection<Long> ids :声明请求参数

  • List<ItemDTO> :返回值类型

在这里我们需要搞清楚消费者和生产者:

 我们是将item-service中的服务进行注册,也就是item-service是生产者
 cart-service是消费者

有了上述信息,OpenFeign就可以利用动态代理帮我们实现这个方法,并且向http://item-service/items发送一个GET请求,携带ids为请求参数,并自动将返回值处理为List<ItemDTO>

我们只需要直接调用这个方法,即可实现远程调用了。

使用FeignClient

最后,我们在cart-servicecom.hmall.cart.service.impl.CartServiceImpl中改造代码,直接调用ItemClient的方法:

连接池

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

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

  • Apache HttpClient :支持连接池

  • OKHttp:支持连接池

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

引入依赖

cart-servicepom.xml中引入依赖(值得注意的是我们是在消费者这边引入依赖):

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

开启连接池

cart-serviceapplication.yml配置文件中开启Feign的连接池功能(值得注意的是我们也是在消费者这边开启连接池功能):

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

重启服务,连接池就生效了。

最佳实践(其就是将消费者client转移统一的模块)

相信大家都能想到,避免重复编码的办法就是抽取。不过这里有两种抽取思路:

  • 思路1:抽取到微服务之外的公共module

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

如图:

方案1抽取更加简单,工程结构也比较清晰,但缺点是整个项目耦合度偏高。

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

由于item-service已经创建好,无法继续拆分,因此这里我们采用方案1.

  抽取Fegin客户端

在自己的父项目定义新的的moduie,命名为xxx-api (由于在黑马上学习的,所以名为hm-api)

其依赖如下:

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <parent>
        <artifactId>hmall</artifactId>
        <groupId>com.heima</groupId>
        <version>1.0.0</version>
    </parent>
    <modelVersion>4.0.0</modelVersion>

    <artifactId>hm-api</artifactId>

    <properties>
        <maven.compiler.source>11</maven.compiler.source>
        <maven.compiler.target>11</maven.compiler.target>
    </properties>

    <dependencies>
        <!--open feign-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-openfeign</artifactId>
        </dependency>
        <!-- load balancer-->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-loadbalancer</artifactId>
        </dependency>
        <!-- swagger 注解依赖 -->
        <dependency>
            <groupId>io.swagger</groupId>
            <artifactId>swagger-annotations</artifactId>
            <version>1.6.6</version>
            <scope>compile</scope>
        </dependency>
    </dependencies>
</project>

现在,任何微服务要调用item-service(原来的没有进行拆解的项目)中的接口,只需要引入hm-api模块依赖即可,无需自己编写Feign客户端了。

扫描包

接下来,我们在cart-service(消费者)pom.xml中引入hm-api模块:

  <!--feign模块-->
  <dependency>
      <groupId>com.heima</groupId>
      <artifactId>hm-api</artifactId>
      <version>1.0.0</version>
  </dependency>

在这里需要注意的是由于我们将client(装有可以远程调用的client放在api)所以在启动的时候回扫描不到,所以我们需要在消费者启动类的
@EnableFeignClients(basePackages = "com.hmall.api.client")
中加上client中的包 就是像上面那样。


http://www.kler.cn/a/537132.html

相关文章:

  • 自动化测试(selenium篇)
  • ASP.NET Core中间件Markdown转换器
  • docker数据持久化的意义
  • CPU的基本结构
  • 广度优先搜索(BFS)算法详解——以走迷宫问题为例
  • 【GitHub】相关工具下载及使用
  • 哪些网站和工具可以用于站点测速和性能分析
  • 深入理解 Java 泛型(Generics)
  • 零基础学习书生.浦语大模型--基础岛
  • Explain 是 SQL 查询优化中非常重要的工具,它用于分析 SQL 查询的执行计划
  • ubuntu20使用tigervnc远程桌面配置记录
  • react的antd组件中上传图片组件,点击预览却打开新页面,将其改为放大预览
  • centos虚拟机迁移没有ip的问题
  • 论文笔记:Rethinking Graph Neural Networks for Anomaly Detection
  • 第8章《VTK交互》
  • 计算机网络知识速记:HTTP与HTTPS
  • 前端知识自检
  • 模板的进阶
  • android camera hal request
  • unity学习31:Video Player 视频播放相关基础
  • 【Axure教程】标签版分级多选下拉列表
  • makefile 的strip,filter,ifeq,ifneq基础使用
  • 朝天椒USB服务器在湖南电力的应用案例
  • docker run和docker exec的区别及开机启动
  • Centos执行yum命令报错
  • NSS-DAY1