了解微服务架构

news2024/11/16 3:28:26

微服务架构

软件架构历史

Software As A Service,这不仅仅是⼀个理念,它更多释放的是企业在新⼀轮的市场竞争中,如何使⽤轻量级的组织架构和新的软件架构来更好的服务企业⾯向未来的战略调整和市场定位,从⽽赢得未来的市场空间。

微服务架构前世今⽣

什么是微服务

使⽤⼀套⼩服务来开发单个应⽤的⽅式,每个服务运⾏在独⽴的进程⾥,⼀般采⽤轻量级的通信机制,并且它们可以通过⾃动化的⽅式部署。“微”是⼀种设计思想,不能使⽤代码量或者开发时间少来进⾏衡量。

微服务的特点

  • 单⼀职责(独⽴的业务单独放在⼀个项目里,⽐如订单服务可以作为⼀个项⽬)
  • 轻量级的通信(HTTP&RPC)
  • 隔离性(每个服务相互隔离,不互相⼲扰)
  • 有自己独⽴的数据库
  • 技术多样性

微服务的诞⽣背景

  • 互联⽹⾏业的快速发展,需求变化快,⽤户数量变化快
  • 敏捷开发深入人心,⽤最小的代价,做最快的迭代,频繁修改,测试,上线
  • 容器技术的成熟,是微服务的技术基础

互联网架构演变之路

在这里插入图片描述

单体架构

传统的应⽤程序是单体架构的模式,具体表现为就是各个模块它是紧耦合的关系,各模块运⾏在⼀个进程中,每次系统升级都需要重新启动整个应⽤程序,如果某个模块存在问题,可能导致整个系统都⽆法正常的使⽤。⽽且从质量管理的⻆度上⽽⾔,基于单体架构的模式,在测试可扩展性以及质量成本投⼊上是⾮常⼤的。
⽐如这⾥我们需要开发⼀个⽆涯教育的平台,那么这个平台就得具备WEB端和移动端的平台属性,同时了我们在单体架构模式的思维中,会把前后端看成是⼀个整体的属性,我们使⽤的中间件就是tomcat的组件,那么它的架构图具体就为:
在这里插入图片描述
如上所属,把前后端以及系统整体的代码整合到⼀起,然后使⽤中间件tomcat容器来进⾏部署和应⽤。此应⽤程序架构意味着,由于团队的紧密性,可以轻松地将新团队成员引⼊应⽤程序。但是,当您因可扩展性或可⽤性要求⽽不得不更改应⽤程序时,您必须在多个计算机上运⾏应⽤程序的多个副本。单体⽤架构可以通过根据组件类型将其划分为不同的层来进⾏逻辑模块化。所有模块和不同层都作为单⼀的神器单⼀应⽤进⾏包装和部署。单体架构的模式也是存在它的优势的,我们不能单纯绝对的就说单体架构模式它都是缺点,毕竟很早期的架构模式就是单体架构的模式的,⽽且是被企业级应⽤很多年,它的优势我们可以总结为:

  • 开发模式简单,⼤家都在⼀个模块中进⾏代码的管理和维护
  • 容易测试可以使⽤端到端的测试模式或者说使⽤Selenium的测试⼯具可以实现端到端的测试
  • 易于部署,直接进⾏处理成.war后,放在tomcat的webapps的⽬录下,就会部署好,没什么技术挑战性
  • 简易缩放:通过将应⽤程序的单⼀⼈⼯制品复制到多个运⾏机器并在单体应⽤程序后⾯设置负载平衡器,您可以轻松实现缩放。

垂直架构

所谓垂直架构,就是对⼤的项⽬进⾏拆分,也就是说对于单体架构的拆分,⼤项⽬拆分成单体项⽬,存在数据冗余。项⽬之间要处理数据同步,⼀般是数据库同步。
在这里插入图片描述

⾯向服务架构(SOA)

SOA称为⾯向服务的架构,主要是为了解决数据冗余的问题,在SOA的架构中,它会分为这么⼏个形态,具体就是:

  • 系统层
  • 访问层
  • 服务层
  • 数据层

核⼼思想就是把重复性的功能进⾏抽取,抽取成对应的服务,通过ESB服务总线去访问。

微服务架构

微服务架构是技术发展的必然趋势,它的核⼼技术和架构理念是实实在在的,基于这个核⼼的理念和架构,也就引领了SAAS(软件即服务)化以及PAAS(平台即服务)化产品的发展趋势。微服务将服务层⼀个⼀个抽取为服务,遵循单⼀原则,微服务之间采⽤⼀些轻量级协议传输数据(RPC或者是REST API)。

微服务架构会把业务系统中的不同模块以微服务的⽅式进⾏拆分,使每个微服务变成⼀个独⽴的Project,独⽴编译以及独⽴部署为⼀个独⽴的进程,每个微服务都可以被部署为多个独⽴的进程对外提供服务,对外接⼝的协议通常是REST或者是RPC,当然还有⼀点需要掌握的,就是不同的微服务进程也可以被部署在多个服务器上。在微服务架构中,所有服务均使⽤ HTTP 或 REST 同步通信,或使⽤ AMQP 或 Kafka 异步通信。每个服务都包含⾃⼰的数据库。微服务架构背后的基本理念是将您的整体应⽤拆分为⼀组更⼩、互联的服务。微服务架构模式将流程层⾯上的问题分开。此架构中的所有过程都松散地相互耦合。他们使⽤预先定义的规则进⾏沟通,以实现业务⽬标。

微服务访问模式

传统访问模式

在这里插入图片描述

微服务架构访问模式

在这里插入图片描述
如上中,我们可以把单体架构模式的应⽤程序都具体的单独分离出来,成⼀个独⽴的应⽤程序服务,然后让服务和服务之间通过REST API的⽅式来进⾏通信。

统⼀访问模式

引⼊⽹关,对客户端暴露⼀套API,⽅便统⼀调⽤和API管理
在这里插入图片描述

微服务架构优点

微服务架构结合容器化,让它具有了天然了优势,这个优势具体可以总结为:

  • 服务拆分粒度⾮常细,利于开发
  • 适⽤于互联⽹更新换代快的情况
  • 易于维护,开发⼈员可以很快速的开发对应的服务
  • 易于缩放:您可以轻松地缩放单个组件
  • 技术多样性:微服务允许您混合库、框架、数据存储和语⾔
  • 故障隔离:组件故障不应使整个系统关闭
  • 更好的⽀持:该架构适⽤于较⼩的并⾏团队
  • 独⽴部署:我们可以轻松独⽴部署每个微服务,⽽不会影响架构中的其他微服务

微服务架构缺点

但是微服务的架构它也是存在缺点的,这些主要可以汇总为:

  • 在服务⼀致性⽅⾯是很难保障的,特别是服务原⼦性这部分
  • 基于分布式很难定位和跟踪故障,过程中需要定位的组件(服务)太多,很难找出到底是那个服务导致问题
  • 微服务架构需要结合DevOps的⽂化来进⾏践⾏,但是很多公司在这⽅⾯还是缺少准备和⽂化氛围。
  • 开发技术要求更⾼,测试的复杂度也是增加

微服务架构模式

微服务部署模式

在微服务的架构体系中,把每个服务实例部署到单独的服务器上,这样的⽬的也是为了提⾼吞吐量和可⽤性,然后在部署的策略下,服务实例可以进⾏隔离。微服务的多个实例在⼀个或多个物理或虚拟主机上运⾏。在此⽅法中,服务的每个实例在⼀台或多个虚拟或物理机器上运⾏在不同的、众所周知的端⼝上。这是⼀种⾮常传统的微服务应⽤部署⽅法,并说明如下图表:
在这里插入图片描述
如上的部署⽅式其实是存在很⼤的问题的,没有办法做到隔离,⽽且服务在资源占⽤上会形成冲突,以及抢占资源的情况,我们可以把每个服务部署的⽅式,形成⼀个独⽴的部署空间,这样可以完全的分割和资源的监控,具体如下:
在这里插入图片描述

微服务通信

微服务通信⽅式

在微服务架构模式中,分布式系统在多个不同的机器上运⾏,每个服务都是企业应⽤的组成部分或过程。这些多台机器的服务必须处理来⾃企业应⽤程序客户端的请求。有时,所有涉及的服务都协作处理此类请求:服务使⽤服务间沟通机制进⾏交互,具体如下:
在这里插入图片描述
因此在微服务的架构模式中,服务和服务之间的通信主要是通过同步通信模式和异步通信的模式来进⾏通信。

同步通信

下⾯具体通过可视化的⽅式来显示同步通信模式中服务和服务之间的交互,具体流程图如下:
在这里插入图片描述
在如上的交互模式中,订单服务发送请求给图书服务,如果图书服务不可⽤,就会导致订单服务的超时,⽽强⼤的耦合意味着图书服务不能⼯作导致订单服务也是不能⼯作的,这个时候可以使⽤Hystrix (Hystrix通过隔离服务之间的访问点、停⽌级联失败和提供回退选项来实现这⼀点,所有这些都可以提⾼系统的整体弹性)来解决这部分。其实服务和服务之间的交互不是单纯的两个服务的交互,更多的是多个服务的交互,⽐如下单购买书籍的流程,就涉及多个服务的交互,具体如下:
在这里插入图片描述
很多时候服务和服务之间的通信都是⼀对⼀的模式,但是也会使⽤SLB的模式来实现服务的负载均衡的机制模式,这样的⽬的也是为了减轻服务端的压⼒模式,它的交互模式为:
在这里插入图片描述

异步通信

基于同步通信的缺陷,然后也就有了异步通信的策略和机制,这种机制主要体现为客户端和服务端通过消息代理来实现通信,具体如下 :
在这里插入图片描述
这些消息代理主要指的是RabbitMQ,Kafka以及ActiveMQ。

⼀对⼀通信

在异步通信的机制中,会存在⼀对⼀的通信⽅式,也会存在⼀对多的通信机制,下⾯具体演示下⼀对⼀的通信机制的交互过程,具体如下:
在这里插入图片描述

⼀对多通信

在这里插入图片描述

服务注册与发现

服务发现需求

在传统或⽼式的应⽤程序架构中,IP 地址和端⼝主要是静态和固定的,因此可以轻松管理客户端应⽤程序。在静态的基于配置的应⽤程序中,每个服务都部署在同⼀位置,我们很少需要更改服务的位置。但是,在基于云的微服务应⽤中,IP 地址和端⼝很难管理,有时甚⾄是不可能的。在微服务架构中,我们不能保证会有静态配置,因为微服务是可独⽴部署的,各个团队在单个微服务上⼯作:每个团队都可以独⽴部署和扩展其微服务。系统中还可以添加更多服务和实例,以提供分布式应⽤程序的可扩展性。由于此缩放,服务位置可能会频繁更改,因此位置不能被视为静态位置。这意味着微服务架构需要更动态的配置。基于现实的部署策略,它的现状可能是如下这样的:
在这里插入图片描述

客户端发现

在基于微服务的应⽤程序中,服务需要相互沟通才能执⾏业务任务。在整体应⽤中,服务之间的沟通⾮常容易,因为所有服务通常是同⼀应⽤的⼀部分。但是,在分布式系统中,服务不是同⼀应⽤的⼀部分。相反,服务在独⽴的虚拟机或容器上运⾏。这些位置(主机和端⼝)是服务的位置,如果应⽤程序向上或向下扩展,则会发⽣变化。这就是服务注册与发现的地⽅。在客户端发现中,客户服务通过查询服务注册处来查找其他服务实例的位置。客户端还负责管理跨服务的负载均衡请求。服务注册处是⼀个⽤于微服务实例的数据库。在客户端,我们必须使⽤算法使⽤⼏个参数选择可⽤实例之⼀。
在这里插入图片描述
如上所示:客户服务本身在注册表服务器上注册。其他微服务也在同⼀注册服务器上注册。所有服务实例均在注册表服务器上的特定位置进⾏注册。客户服务使⽤注册的服务名称,并在实例终⽌时从服务注册处删除。服务实例的注册通常使⽤⼼跳机制定期刷新。

服务端发现

在微服务架构中,实现服务发现⾮常重要。这使客户端应⽤程序能够在没有硬编码的⽹络位置的情况下搜索服务。我们可以通过两种⽅式实施服务发现模式:通过客户端发现和服务端发现,下⾯主要详解服务端发现的模式。在服务器端发现模式中,客户端不知道服务注册表。客户服务使⽤负载均衡请求服务,然后查询服务注册处,在服务器端服务发现模式中,客户端⽆需担⼼管理⽤于负载平衡和发现服务的代码或算法。相反,我们可以使⽤单独的负载均衡服务器。具体交互如下:
在这里插入图片描述
如上所示,客户服务直接向负载平衡器提出请求,该平衡器会查询服务注册处,然后找到服务。

API GateWay

⽹关概述

API⽹关是⼀个服务器,是系统的唯⼀⼊⼝。从⾯向对象设计的⻆度看,它与外观模式类似。API⽹关封装了系统内部架构,为每个客户端提供⼀个定制的API。它可能还具有其它职责,如身份验证、监控、负载均衡、缓存、请求分⽚与管理、静态响应处理。API⽹关⽅式的核⼼要点是,所有的客户端和消费端都通过统⼀的⽹关接⼊微服务,在⽹关层处理所有的⾮业务功能。通常,⽹关也是提供REST/HTTP的访问API。
在这里插入图片描述
在如上的交互中,我们看到客户端发送请求到,先到API GateWay,然后再发送请求到服务端这⼀层。使⽤APIGateWay主要具备如下的优势,具体为:

  • 在客户端与服务端之间做了隔离,这样可以对客户端的请求做限流以及在⾼并发的情况下防⽌服务端的崩溃
  • 在API GateWay这层可以做API的监控,API的请求限流,以及统⼀的安全认证体系

⽹关层响应

⼤型的应⽤程序架构⽹络层⾯是⾮常复杂的,通常都是多层⽹关构建起来的⼀套复杂的⽹络环境,⼀个客户端发送Request请求后,到后台服务接收该请求并处理的这个过程,这个过程中客户端请求会经过多个⽹关层和多次⽹络转发。
在这里插入图片描述

DNS服务器

DNS服务器其实是Domain Name Server的简称,客户端发送的Request请求⾸先抵达DNS服务器,解析并获取域名对应的IP地址。

LVS集群

经过DNS的集群后,⼀个域名可以对应多个IP的地址,⽽IP指向LVS技术搭建的虚拟IP的地址,其实本质上⽽⾔就是Nginx之类的⽹关层集群,对调⽤的应⽤程序⽽⾔,请求发送到虚拟IP的地址,下来再由LVS做负载均衡,从⽽转发到⽹关集群中的某⼀台⽹关服务器。

Nginx⽹关服务器

Nginx是⼀款⾼性能WEB和反向代理组件,具备很强的并发连接能⼒,可以⽀撑⾼并发场景的需求,主要是对计算资源占⽤也是⽐较少,⽬前主要应⽤于⽹关层的组件。在DNS和服务⽹关之间搭建多层LVS+Nginx的⽹关层集群,来应对不同⾼并发下内⽹转发的需求。

微服务⽹关

微服务的⽹关主要是SpringCloud Gateway组件来发挥具体的作用,它不是直接暴露给客户端,⽽是在Nginx外部⽹关集群和内部服务集群之间,可以理解为在内部⽹络环境中,通过来接收Nginx⽹关服务器转发来的流量,外部的⽤户是⽆法直接访问⽹关层的。在Saas化的架构下,微服务⽹关更多时候会被设计成⼀个服务,通过服务注册流程把⾃⼰添加到服务注册中⼼⾥⾯,这样⽤户发送请求过来,微服务⽹关通过负载均衡的策略机制,把服务的请求转发到应⽤服务的节点。

SpringCloud实战

在Java的技术栈体系中,微服务的架构主要是基于SpringCloud,下⾯主要演示SpringCloud的框架来实现⼀个微服务架构的产品。

架构流通图

整体流程图的思想就是“服务消费者”从“服务中⼼”获取“服务⽣产者”信息后调⽤集群的功能。它的整体架构图如下所示:
在这里插入图片描述

创建步骤

依据上⾯的架构图,可以得到它的具体步骤可以描述为:

  • 用Eureka实现⼀个“服务中⼼”集群;
  • 通过Eureka的“服务注册”的功能来注册“服务提供者”,以实现“服务提供者”集群;
  • “服务消费者”不需要注册到“服务中心”来,它主要是使⽤Eureka的“服务注册”的功能根据“服务提供者”注册的名称来调⽤客户端Feign以消费“服务提供者”提供的接⼝;
  • 启动程序的顺序是先启动“服务中心”集群,下来是“服务提供者”集群,最后启⽤“服务消费者”客户端来测试和消费服务。

创建SpringCloud项⽬

创建MAVEN项⽬

我们⾸先来创建maven的⼯程,在创建新的项⽬中,也就是maven的项⽬,选择maven-archetype-webapp,具体如下所示:
在这里插入图片描述

注册中⼼

在新创建的maven项⽬中,选中项⽬,然后点击File,点击New当中的Module,具体如下
在这里插入图片描述
点击Module,选择Spring Assistant,具体如下:
在这里插入图片描述
然后点击下⼀步,选择⼯程的具体信息,⼯程名字为Eureka-Server,点击下⼀步后,我们选择Eureka Server,具体如下:
在这里插入图片描述
创建成功后,在EurekaServerApplication的源码⾥⾯,新增Eureka Server的信息,具体代码为
@EnableEurekaServer,修改后的代码为:

package com.example.demo;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@SpringBootApplication
@EnableEurekaServer
public class EurekaServerApplication
{
   public static void main(String[] args)
   {
      SpringApplication.run(EurekaServerApplication.class, args);
   }
}

把配置⽂件修改为application.yaml,具体内容为:

server:
  #运⾏端⼝
  port: 8081
eureka:
  instance:
  #注册ip
  hostname: localhost
  client:
    #⾃⼰当做服务注册
    register-with-eureka: true
    #显示注册信息
    fetch-registry: true
    #注册url
    serviceUrl:
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

项⽬整体结构具体如下所示:
在这里插入图片描述

服务中⼼集群

下⾯实现在⼀个电脑上实现服务中⼼的集群,我们⾸先配置多个配置⽂件,配置⽂件的名称分别是application-node1.yaml,application-node2.yaml和application-node3.yaml。在本地host⽂件中新增如下内容:

# End of section
127.0.0.1 node1
127.0.0.1 node2
127.0.0.1 node3

下⾯来完善各个配置⽂件,application-node1.yaml的内容为:

server: 
  #运⾏端⼝
  port: 8082
eureka:
  instance: 
    #节点的名称 
    hostname: node1
  client:
    #⾃⼰当做服务注册 
    register-with-eureka: true 
    #显示注册信息 
    fetch-registry: true 
    #注册url
    serviceUrl:
      defaultZone: http://node2:8083/eureka/,http://node3:8084/eureka/

application-node2.yaml的内容为:

server:
  #运⾏端⼝
  port: 8083
eureka:
  instance:
    #节点的名称
    hostname: node2
  client:
    #⾃⼰当做服务注册
    register-with-eureka: true
    #显示注册信息
    fetch-registry: true
    #注册url
    serviceUrl:
      defaultZone: http://node1:8082/eureka/,http://node3:8084/eureka/

application-node3.yaml的内容为:

server:
  #运⾏端⼝
  port: 8084
eureka:
  instance:
    #节点的名称
    hostname: node3
  client:
    #⾃⼰当做服务注册
    register-with-eureka: true
    #显示注册信息
    fetch-registry: true
    #注册url
    serviceUrl:
      defaultZone: http://node1:8082/eureka/,http://node2:8083/eureka/

打包服务中⼼

在⼯程中这些mvn clean,进⾏打包,接着执⾏mvn package,具体如下所示:
在这里插入图片描述
打包成功后,会在⼯程下⽣成target⽂件夹,⾥⾯就有我们需要的jar的⽂件,也就是⽂件kureka-server-0.0.1-SNAPSHOT.jar,具体如下所示:
在这里插入图片描述

服务中⼼集群部署

进⼊到target的⽬录,分别以node1,node2,node3的配置参数来启动,也就是使⽤三个控制台来进⾏启动,具体命令如下:

java -jar kureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=node1
java -jar kureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=node2
java -jar kureka-server-0.0.1-SNAPSHOT.jar --spring.profiles.active=node3

启动成功后,在浏览器输⼊http://node1:8082/,服务中⼼显示的界⾯如下:
在这里插入图片描述
在这里插入图片描述
备注:从如上得知,node2和node3展示在available-replicas,主要显示这些节点的信息,如果停⽌node2和node3,就会显示在unavailable-replicas中。

服务提供者

启⽤注册发现机制

下来使⽤Eureka来实现服务提供者,创建项⽬和之前⼀样,只不过不再勾选Eureka Server,⽽是勾选EurekaDiscovery Client,具体如下:
在这里插入图片描述
把配置⽂件从application.properties修改为application.yaml,配置⽂件添加信息如下:

eureka:
  client:
  serviceUrl:
  #服务注册地址
  defaultZone: 
http://node1:8082/eureka/,http://node2:8083/eureka/,http://node3:8084/eureka/
  server:
    #运⾏端⼝
    port: 8000
  spring:
    application: 
      #服务注册名称 
      name: producer
  producer:
    name: producer0

在程序中启⽤注册和发现的机制,新增@EnableDiscoveryClient,完善后的代码如下:

package com.example.producer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
#启⽤客户端的服务注册与发现
@EnableEurekaClient
public class ProducerApplication
{
   public static void main(String[] args)
   {
      SpringApplication.run(ProducerApplication.class, args);
   }
}

服务提供者API

下来编写服务提供者API的应⽤程序的接⼝信息,ProducerController.java的源码为:

package com.example.producer;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ProducerController
{
   @Value("${spring.application.name}") 
   private String name; 
   @Value("${server.port}")
   private String port;
   /*提供API信息,⽤于返回客户端发送请求后的响应数据*/ 
   @RequestMapping("/index")
   public String Hello()
   {
      String str="producer:"+name+"port:"+port; 
      //返回数据
      return str;
   } 
}

检查服务有效性

检查的顺序是启动服务中⼼的集群,然后再启动服务提供者的应⽤程序。下来在http://node1:8082/的服务中⼼查看服务提供者是否注册成功,如果注册成功就会显示在Instances currently registered with Eureka中,并且显示服务提供者的服务名称,具体如下:
在这里插入图片描述
备注:如上可以查看到,服务提供者已经被注册成功。下⾯在PostMan测试⼯具中调⽤http://localhost:8000/index,就会显示如下的结果信息,具体如下:
在这里插入图片描述

服务提供者集群

在服务提供者创建新的配置⽂件,分别是application-producer1.yaml和application-producer2.yaml,具体如下所示:
在这里插入图片描述
application-producer1.yaml配置⽂件的内容为:

eureka:
  client:
    serviceUrl:
      #服务注册地址
      defaultZone: 
http://node1:8082/eureka/,http://node2:8083/eureka/,http://node3:8084/eureka/
server:
  #运⾏端⼝
  port: 8001
spring:
  application:
    #服务注册名称
    name: producer
producer:
  name: producer1

application-producer2.yaml配置⽂件内容为:

eureka:
  client:
    serviceUrl:
      #服务注册地址
      defaultZone: 
http://node1:8082/eureka/,http://node2:8083/eureka/,http://node3:8084/eureka/
server:
  #运⾏端⼝
  port: 8002
spring:
  application:
    #服务注册名称
    name: producer
producer:
  name: producer2

打包启动

下来对服务提供者使⽤命令mvn clean和mvn package打包后,来进⾏启动,⻅打包后的信息:

[INFO] Results:
[INFO]
[INFO] Tests run: 1, Failures: 0, Errors: 0, Skipped: 0
[INFO]
[INFO]
[INFO] --- maven-jar-plugin:3.2.0:jar (default-jar) @ producer ---
[INFO] Building jar: /Applications/code/workSpace/app/producer/target/producer-0.0.1- 
SNAPSHOT.jar
[INFO]
[INFO] --- spring-boot-maven-plugin:2.5.3:repackage (repackage) @ producer ---
[INFO] Replacing main artifact with repackaged archive
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------

下来来启动服务提供者集群,启动的命令具体如下:

java -jar producer-0.0.1-SNAPSHOT.jar --spring.profiles.active=producer1
java -jar producer-0.0.1-SNAPSHOT.jar --spring.profiles.active=producer2

启动服务提供者的程序后,在服务中⼼就可以看到注册的信息,具体如下所示:
在这里插入图片描述

服务消费者(Feign)

创建Eureka客户端

⾸先我们来创建Eureka客户端的项⽬,也就是只选择Eureka Discovery Client,具体如下:
在这里插入图片描述
创建项⽬成功后,把application.properties修改为application.yaml,内容完善如下:

eureka:
    client:
        serviceUrl:
        #服务注册地址 
        defaultZone: 
http://node1:8082/eureka/,http://node2:8083/eureka/,http://node3:8084/eureka/
        #不注册到服务中⼼
        register-with-eureka: false
    server:
        #运⾏端⼝
        port: 9000
        spring:
            application:
                #服务注册名称 
                name: consumer

调⽤服务提供者接⼝

启⽤客户端发现和远程调⽤

在ConsumerApplication.java的应⽤程序⾥⾯增加注解,具体为@EnableEurekaClient,@EnableFeignClients,具体源码如下:

package com.example.consumer;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.openfeign.EnableFeignClients;
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients
public class ConsumerApplication 
{
   public static void main(String[] args)
   {
      SpringApplication.run(ConsumerApplication.class, args);
   }
}

调⽤服务提供者接⼝

Feign可以把它理解为⼀个申明式的WebService客户端,使⽤Feign可以编写优秀的WebService客户端更加简单,具体步骤为:

  • 添加依赖
<dependency>
   <groupId>org.springframework.cloud</groupId>
   <artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
  • 启动类添加注解@EnableFeignClients
  • 定义⼀个接⼝,在接⼝中添加注解⽅便使⽤,定义接⼝MyFeignClient,源码如下:
package com.example.consumer;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
@FeignClient(name = "producer")
public interface MyFeignClient
{
   @RequestMapping(value = "/index")
   public String index();
}
  • 把接⼝的信息注⼊到Controller层,ConsumerController.java的源码为:
package com.example.consumer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class ConsumerController
{
   @Autowired
   MyFeignClient myFeignClient;
   @RequestMapping("/index")
   public String index()
   {
      return myFeignClient.index();
   }
   @RequestMapping("/login")
   public String login()
   {
      return "⽆涯课堂为您服务!";
   }
}

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

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

相关文章

【计算机视觉 | 图像分割】arxiv 计算机视觉关于图像分割的学术速递(7 月 6 日论文合集)

文章目录 一、分割|语义相关(15篇)1.1 Prompting Diffusion Representations for Cross-Domain Semantic Segmentation1.2 ZJU ReLER Submission for EPIC-KITCHEN Challenge 2023: Semi-Supervised Video Object Segmentation1.3 Multi-Modal Prototypes for Open-Set Semanti…

基于YOLO的3D人脸关键点检测方案

目录 前言一、任务列表二、3D人脸关键点数据H3WB2.下载方法3.任务4.评估5.使用许可 3DFAWAFLW2000-3D 三、3D关键点的Z维度信息1.基于3DMM模型的方法2.H3WB 四、当前SOTA的方法1.方法1 五、我们的解决方法1.数据转为YOLO格式2.修改YOLO8Pose的入口出口3.开始训练&#xff0c;并…

aardio 的addHeaders请求

aardio群 625494397 废话不多说 直接开干&#xff01; import web.json; import console; import inet.whttp; web.json.parse( json );//转化json格式 h.addHeaders {Accept-Encoding gzip, deflate, br;Accept-Language zh-CN,zh;q0.9;User-Agent Mozilla/5.0 (Windows …

浅谈智能照明控制管理系统的功能介绍

安科瑞电气股份有限公司 上海嘉定 201801 摘要&#xff1a;智能照明控制系统较好地实现了智能控制、人性化照明和节能降耗的功能,使其在楼宇控制领域变得越来越重要,越来越受到人们的重视。本文介绍了智能照明控制系统的概念、特点、优势、发展方向等内容,并着重对智能照明控制…

多个项目的进度管理:掌握这3点,轻松应对

在现代的企业竞争中&#xff0c;许多企业组织都会同时进行多个项目。而有效的进度管理对于确保项目按时交付和优化资源利用至关重要。那么有哪些方法可以帮助项目管理者掌握多个项目的进度管理呢&#xff1f; 一&#xff1a;明确目标和优先级 在管理多个项目时&#xff0c;明确…

windows系统使用nvm实现多版本node切换

介绍nvm 是 node version manager&#xff08;node 版本管理工具&#xff09;的缩写&#xff0c;是一个命令行工具&#xff0c;用于管理和切换到不同版本的 node.js。 不同的项目可能需要不同版本的 node.js 和 npm&#xff08;node 包管理器&#xff09;&#xff0c;例如&…

增强型视觉系统 (EVS)

增强型视觉系统 EVS 1、增强型视觉系统概览2、车载相机 HAL2.1 EVS 应用2.2 EVS 管理器2.3 EVS HIDL 接口2.4 内核驱动程序 《增强型视觉系统 (EVS) 1.1 集成指南》 车载相机 HAL 1、增强型视觉系统概览 为了增强视频串流管理和错误处理&#xff0c;Android 11 更新了车载相机…

OD查找偏移表达式

1、在CE中先找到血地址2DF94C28 2、在od数据段dd 血地址 dd 2DF94C28查找到数据 3、在血地址位置右键-断点-硬件访问-DWORD&#xff0c;再操作游戏会再改变这个地址代码段下断点&#xff0c;查找到 4、验证查找的是否正确&#xff0c;在8199FA处下断点&#xff0c;dd edi288处…

github port 22 connection refused 不通过科学上网连接不上问题

原因是用密钥连接github走的是ssh&#xff0c;ssh默认端口是22没有加密&#xff0c;github不让走22 解决办法是在 ~/.ssh/config里添加 Host github.com Hostname ssh.github.com Port 443 让ssh连github的时候走443端口&#xff0c;TLS加密的 ssh -T gitgithub.com 说明已…

Docker深入

一、简介 Docker是一个用于构建、运行、传送应用程序的平台。 2、为什么使用Docker 在部署服务器过程中&#xff0c;配置各种环境变量、第三方依赖等等&#xff0c;耗费时间太长&#xff0c;使用Docker可以将他们打包成一个集装箱&#xff0c;只要在开发环境中运行成功&…

Hive 复习重点

文章目录 特点SQL查询转换成MR作业的过程内部表 & 外部表 & 分区表 & 分桶表内部表外部表分区表 分桶表DQL语法性能优化SQL语句优化数据格式化 ORC, Parquet列式存储小文件过多优化并行执行优化JVM 优化推测执行行列过滤limit 限制本地模式(开启MR&#xff0c;单机…

stm32mp157——通过按键中断实现LED灯的亮灭

EXTI章节初始化 void hal_exit_init(EXTI编号,GPIOF组编号,中断触发方式) 调用:hal_exit_init(EXTI9,0x05,下降沿触发) 调用: hal_exit_init(EXTI7,0x05,下降沿触发) 调用: hal_exit_init(EXTI8,0x05,下降沿触发) GIC章节初始化 void hal_gic_init(中断号,中断优先级) 调用: ha…

Redis - 一篇讲解根据 Key 前缀统计分析内存占用

问题描述 今天遇到一个 Redis 内存打挂了的问题&#xff0c;想看看哪个前缀 Key 占用内存比较大&#xff1f;&#xff01; 原因分析 我们都知道如果直接用 Keys 参数去做统计很危险&#xff0c;而且也只能统计数量&#xff0c;当然也可以排序去前几名的占用内存 Key 对应的大…

ESP32(掌控板) 电子琴

ESP32&#xff08;掌控板&#xff09; 电子琴 本程序实现了电子琴功能&#xff0c;通过机械按键改变变量的值实现“翻页”&#xff08;每个八度分两页&#xff0c;共六页&#xff09;&#xff0c;通过触摸按键弹奏&#xff08;包含半音&#xff09;&#xff0c;屏幕显示当前触摸…

基于微信小程序充电桩预约管理系统的设计与实现(论文+源码)_kaic

摘要 微信小程序的充电桩预约管理系统是一个复杂的系统&#xff0c;需要遵循不同的设计原则和方法&#xff0c;在实现高可用性、高性能、高安全性和高稳定性等特点的同时&#xff0c;还要注重用户体验和易用性&#xff0c;不断改进和迭代优化&#xff0c;以提高系统性能和用户满…

replicaSet,DaemonSet and Job

ReplicaSet 上一篇讲到的 ReplicationController 是用于复制和在异常的时候重新调度节点的 K8S 组件&#xff0c;后面 K8S 又引入了 ReplicaSet 资源来替代 ReplicationController ReplicationController 和 ReplicaSet 有什么区别呢&#xff1f; ReplicationController 和 …

Java中一个类可以继承多个类吗?揭秘多重继承的秘密!

大家好&#xff0c;我是你们的小米&#xff01;今天&#xff0c;我们来聊聊Java中一个备受争议的话题——"一个类可以继承多个类吗&#xff1f;"这是一个让许多Java初学者困惑的问题&#xff0c;也是一个常常被问及的热门话题。那么&#xff0c;到底Java中是否允许一…

Multi-Aspect Explainable Inductive Relation Prediction by Sentence Transformer

摘要 最近关于知识图(KGs)的研究表明,通过预先训练的语言模型授权的基于路径的方法在提供归纳和可解释的关系预测方面表现良好。本文引入关系路径覆盖率和关系路径置信度的概念,在模型训练前过滤掉不可靠的路径,以提高模型的性能。此外,我们提出了知识推理句子转换器(Know…

MySQL索引介绍及底层数据结构B+树介绍

索引 1. 索引概述1.1 索引1.2 索引的优缺点1.2.1 优点1.2.2 缺点 2. InnoDB中的索引2.1 主键索引设计方案2.2 索引底层数据结构2.3 常见索引2.3.1 聚簇索引2.3.1.1 优点2.3.1.2 缺点 2.3.2 非聚簇索引2.3.3 联合索引 3. MyISAM中的索引3.1 MyISAM 与 InnoDB对比 1. 索引概述 1…

代码随想录算法训练营第59天 | 503.下一个更大元素 II + 42.接雨水

今日任务 目录 503.下一个更大元素 II - Medium 42.接雨水 - Hard 503.下一个更大元素 II - Medium 题目链接&#xff1a;力扣-503. 下一个更大元素 II 给定一个循环数组 nums &#xff08; nums[nums.length - 1] 的下一个元素是 nums[0] &#xff09;&#xff0c;返回 nu…