微服务架构
软件架构历史
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 "⽆涯课堂为您服务!";
}
}