随着互联⽹的发展,⽤户群体逐渐扩大,⽹站的流量成倍增⻓,常规的单体架构已⽆法满⾜请求压⼒和业务的快速迭代,架构的变化势在必⾏。下⾯从最开始的单体架构分析,⼀步步的到现在的微服务架构。
在诞⽣之初,应用的⽤户量、数据量规模都⽐较⼩,项目所有的功能模块都放在一个工程中编码、编译、打包并且部署在一个 Tomcat 容器中的架构模式就是单体应用架构,这样的架构既简单实 ⽤、便于维护,成本⼜低,成为了那个时代的主流架构⽅式。
Actor -> Application Server -> Database
优点:
单体架构的应用比较容易部署、测试, 在项目的初期,单体应用可以很好地运行。然而,随着需求的不断增加, 越来越多的人加入开发团队,代码库也在飞速地膨胀。慢慢地,单体应用变得越来越臃肿,可维护性、灵活性逐渐降低,维护成本越来越高。
缺点:
业务量上涨之后,单体应用架构进一步丰富变化,比如应用集群部署、使用 Nginx 进行负载均衡、增加缓存服务器、增加文件服务器、数据库集群并做读写分离等,通过以上措施增强应对高并发的能力、应对一定的复杂业务场景,但依然属于单体应用架构。
Actor -> Nginx 反向代理 -> [FastDFS, Tomcat 集群]
Tomcat 集群
-> {Application Server, Application Server, Application Server}
-> [MySQL 集群, 缓存服务器]
为了避免上⾯提到的问题,开始做模块的垂直划分,做垂直划分的原则是基于应用现有的业务特性来做,核心目标标第⼀个是为了业务之间互不影响,第⼆个是在研发团队的壮⼤后为了提⾼效率,减少组件之间的依赖。
Actor
-> [单点登录,主站,简历管理,职位管理,公司入驻,Admin 系统]
-> ES 集群、Redis 集群、MySQL 集群、文件集群
优点:
缺点:
在做了垂直划分以后,模块随之增多,维护的成本在也变⾼,⼀些通⽤的业务和模块重复的越来越多,为了解决上⾯提到的接⼝协议不统⼀、服务⽆法监控、服务的负载均衡,引⼊了阿⾥巴巴开源的 Dubbo ,⼀款⾼性能、轻量级的开源 Java RPC 框架,可以和 Spring 框架无缝集成。它提供了三⼤核⼼能⼒:⾯向接⼝的远程⽅法调⽤,智能容错和负载均衡,以及服务⾃动注册和发现。
SOA - Service-Oriented Architecture,即面向服务的架构。根据实际业务,把系统拆分成合适的、独立部署的模块,模块之间相互独立(通过 Webservice / Dubbo 等技术进行通信)。
优点:分布式、松耦合、扩展灵活、可重用。
缺点:服务抽取粒度较大、服务调用方和提供方耦合度较高(接口耦合度)。
服务注册与发现: Zookeeper
展示层 -> 业务服务层 -> 基础业务层 -> 基础服务层 -> 存储层
展示层 -> [单点登录,主站,...,Admin 系统]
业务服务层 -> [简历投递,职位搜索,职位推荐,人才搜索,人才推荐,开通招聘服务,任务中心...]
基础业务层 -> [账户基础服务,简历基础服务,公司基础服务,职位基础服务...]
基础服务层 -> [消息服务,短链接,附件解析,定时任务平台...]
存储层 -> [MySQL, MongoDB, ES, FastDFS...]
微服务架构可以说是 SOA 架构的一种拓展,这种架构模式下它拆分粒度更小、服务更独立。把应用拆分成为一个个微小的服务,不同的服务可以使用不同的开发语言和存储,服务之间往往通过 Restful 等轻量级通信。微服务架构关键在于微小、独立、轻量级通信。
微服务是在 SOA 上做的升华粒度更加细致,微服务架构强调的⼀个重点是业务需要彻底的组件化和服务化。
Nginx 负载均衡(Keepalived 高可用)
-> 网关集群(GateWay 1, GateWay2, GateWay3 ...)
--route--> [单点登录,主站,...,Admin 系统]
-> [简历投递,职位搜索,职位推荐,人才搜索,人才推荐,开通招聘服务,任务中心...]
-> [账号基础服务,简历基础服务,公司基础服务,职位基础服务...]
-> [消息服务,短链接,附件解析,定时任务平台...]
-> [MySQL, MongoDB, ES, FastDFS]
服务注册和发现中心:Eureka 集群(Eureka 1, Eureka 2, Eureka 3,,,)
配置中心
日志服务
消息服务
微服务架构和 SOA 架构很明显的一个区别就是服务拆分粒度的不同,上述看到的是应用架构演变的阶段结果,每一个阶段其实都经历了很多变化,服务拆分其实也是走过了从粗到细,并非绝对的一步到位。
比如,在 SOA 架构的初期,“简历投递模块”和“人才搜索模块”都有简历内容展示的需求,只不过说可能略有区别,一开始在两个模块中各维护了一套简历查询和展示的代码;后期将服务更细粒度拆分,拆分出简历基础服务,那么不同模块调用这个基础服务即可。
微服务架构设计的核心思想就是“微”,拆分的粒度相对比较小,这样的话单一职责、开发的耦合度就会降低、微小的功能可以独立部署扩展、灵活性强,升级改造影响范围小。
微服务架构和微服务的优点:
微服务架构的缺点:
例如:服务提供者 - 简历服务,服务消费者 - 职位搜索。
服务注册:服务提供者将所提供服务的信息(服务器 IP 和端口、服务访问协议等)注册 / 登记到注册中心。
服务发现:服务消费者能够从注册中心获取到较为实时的服务列表,然后根究一定的策略选择一个服务访问。
服务消费者启动时,需要将自己注册到服务注册中心。
服务注册中心 <--注册中心客户端--> 服务消费者()
[服务提供者 A, 服务提供者 B,服务提供者 C] --注册中心客户端--> 服务注册中心
负载均衡即将请求压力分配到多个服务器(应用服务器、数据库服务器等),以此来提高服务的性能、可靠性。
用户 --请求--> 负载均衡器 --> [服务实例 A,服务实例 B,服务实例 C]
熔断即断路保护。微服务架构中,如果下游服务因访问压力过大而响应变慢或失败,上游服务为了保护系统整体可用性,可以暂时切断对下游服务的调用。这种牺牲局部,保全整体的措施就叫做熔断。
服务 A -> 服务 B -> 服务 C
下游服务:服务 B、服务 C
熔断器:1.熔断;2.服务降级,返回默认数据
微服务架构越发流行,一个项目往往拆分成很多个服务,那么一次请求就需要涉及到很多个服务。不同的微服务可能是由不同的团队开发、可能使用不同的编程语言实现、整个项目也有可能部署在了很多服务器上(甚至百台、千台)横跨多个不同的数据中心。所谓链路追踪,就是对一次请求涉及的很多个服务链路进行日志记录、性能监控。
用户
--请求-traceid1--> 接口
--spanid1-traceid1-parentid0-timestamp--> 服务 A
--spanid2-traceid1-parentid1-timestamp--> 服务 B
--spanid3-traceid1-parentid2-timestamp--> 服务 C
微服务架构下,不同的微服务往往会有不同的访问地址,客户端可能需要调用多个服务的接口才能完成一个业务需求,如果让客户端直接与各个微服务通信可能出现:
1)客户端需要调用不同的 url 地址,增加了维护调用难度。
2)在一定的场景下,也存在跨域请求的问题(前后端分离就会碰到跨域问题,原本我们在后端采用 Cors 就能解决,现在利用网关,那么就放在网关这层做好了)。
3)每个微服务都需要进行单独的身份认证。
那么,API 网关就可以较好的统一处理上述问题,API 请求调用统一接入 API 网关层,由网关转发请求。API 网关更专注在安全、路由、流量等问题的处理上(微服务团队专注于处理业务逻辑即可),它的功能比如:
[IoT, Mobile, Browser] --> 平台(如 CloudFoundry)
平台(如 CloudFoundry):
API GateWay
<---> [Spring Boot Apps, Spring Boot Apps, Spring Boot Apps]
<--->
{
[Config Server, Service Registry, Circuit Breaker Dashboard],
[Metrics Store, Databases, Message Brokers]
}
Spring Cloud Sleuth
Spring Cloud 是一系列框架的有序集合。它利用 Spring Boot 的开发便利性巧妙地简化了分布式系统基础设施的开发,如服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等,都可以用 Spring Boot 的开发风格做到一键启动和部署。Spring Cloud 并没有重复制造轮子,它只是将目前各家公司开发的比较成熟、经得起实际考验的服务框架组合起来,通过 Spring Boot 风格进行再封装屏蔽掉了复杂的配置和实现原理,最终给开发者留出了一套简单易懂、易部署和易维护的分布式系统开发工具包。
Spring Cloud 是一系列框架的有序集合;
Spring Cloud 是一个规范;
Spring Cloud 具有服务发现注册、配置中心、消息总线、负载均衡、断路器、数据监控等;
Spring Cloud 利用 Spring Boot 的开发便利性简化了微服务架构的开发(自动装配)。
需要注意,Spring Cloud 其实是一套规范,是一套用于构建微服务架构的规范,而不是一个可以拿来即用的框架(所谓规范就是应该有哪些功能组件,然后组件之间怎么配合,共同完成什么事情)。在这个规范之下第三方的 Netflix 公司开发了一些组件、Spring 官方开发了一些框架 / 组件,包括第三方的阿里巴巴开发了一套框架 / 组件集合 Spring Cloud Alibaba,这些才是 Spring Cloud 规范的实现。
Spring Cloud 规范及实现意图要解决的问题其实就是微服务架构实施过程中存在的一些问题,比如微服务架构中的服务注册发现问题、网络问题(比如熔断场景)、统一认证安全授权问题、负载均衡问题、链路追踪等问题。
如前所述,Spring Cloud 是一个微服务相关规范,这个规范意图为搭建微服务架构提供一站式服务,采用组件(框架)化机制定义一系列组件,各类组件针对性的处理微服务中的特定问题,这些组件共同来构成 Spring Cloud 微服务技术栈。
Spring Cloud 生态圈中的组件,按照发展可以分为第一代 Spring Cloud 组件和第二代 Spring Cloud 组件。
第一代 Spring Cloud(Netflix,SCN):
+ 注册中心 - Netflix Eureka
+ 客户端负载均衡 - Netflix Ribbon
+ 熔断器 - Netflix Hystrix
+ 网关 - Netflix Zuul:性能一般,未来将退出 Spring Cloud 生态圈
+ 配置中心 - 官方 Spring Cloud Config
+ 服务调用 - Netflix Feign
+ 消息驱动 - 官方 Spring Cloud Stream
+ 链路追踪 - 官方 Spring Cloud Sleuth/Zipkin
第二代 Spring Cloud(主要就是 Spring Cloud Alibaba,SCA):
+ 注册中心 - 阿里巴巴 Nacos
+ 客户端负载均衡 - 阿里巴巴 Dubbo LB、Spring Cloud Loadbalancer
+ 熔断器 - 阿里巴巴 Sentinel
+ 网关 - 官方 Spring Cloud Gateway
+ 配置中心 - 阿里巴巴 Nacos、携程 Apollo
+ 服务调用 - 阿里巴巴 Dubbo RPC
+ 事务 - 阿里巴巴 seata 分布式事务方案
用户 --API 调用--> API 网关(重试机制、负载均衡、熔断机制)
API 网关
--调用服务-->
[
服务消费者(Hystrix 断路器/熔断器、Ribbon/Feign 负载均衡器/远程调用),
服务提供者(Service A,Service B,Service C)
]
服务消费者 --调用内部服务--> 服务提供者
注册中心集群 ---- [Instance A <---> Instance B <---> Instance C]
服务提供者 --注册--> 注册中心集群
配置中心集群 --注册--> 注册中心集群
服务提供者 <--获取配置内容-- 配置中心集群:
配置中心集群 --发送消息--> 消息总线 --消息--> 服务提供者
Spring Cloud 中的各组件协同工作,才能够支持一个完整的微服务架构。比如:
Dubbo 是阿里巴巴公司开源的一个高性能优秀的服务框架,基于 RPC 调用,对于目前使用率较高的 Spring Cloud Netflix 来说,它是基于 HTTP 的,所以效率上没有 Dubbo 高,但问题在于 Dubbo 体系的组件不全,不能够提供一站式解决方案,比如服务注册与发现需要借助于 Zookeeper 等实现,而 Spring Cloud Netflix 则是真正的提供了一站式服务化解决方案,且有 Spring 大家族背景。
前些年,Dubbo 使用率高于 SpringCloud,但目前 Spring Cloud 在服务化 / 微服务解决方案中已经有了非常好的发展趋势。
OSI 模型:
+ 应用层 - Telnet、FTP、HTTP、SNMP,数据流
+ 表示层 - CSS、GIF、HTML、JSON、XML、GIF,数据流
+ 会话层 - FTP、SSH、TLS、HTTP(s)、SQL,数据流
+ 传输层 - TCP、UDP,数据段
+ 网络层 - IP(IPV4/IPV6)、ICMP,数据包
+ 数据链路层 - 802.2、802.3ATM、HDLC,帧
+ 物理层 - V.35、EIA/TIA-232,比特流
实际开发的分层(TCP/IP):
应用层 -- OSI 模型 [应用层、表示层、会话层]
传输层 -- OSI 模型传输层
网际层 -- OSI 模型网络层
网络接口层 -- OSI 模型 [数据链路层、物理层]
Spring Cloud 只是利用了 Spring Boot 的特点,让开发人员能够快速的实现微服务组件开发,否则不使用 Spring Boot 的话,在使用 Spring Cloud 时,每一个组件的相关 Jar 包都需要手动导入配置以及需要开发人员考虑兼容性等各种情况。所以 Spring Boot 是开发人员快速把 Spring Cloud 微服务技术应用起来的一种方式。
需求:
服务消费者:静态化微服务,生成静态页。
服务提供者:商品微服务,商品管理。
静态化微服务 --商品ID--> 商品微服务
商品微服务拿到 id 之后,在数据库中查询 id 对应的商品信息,返回给静态化服务。
通常用户点击某个商品后,此时打开的网页其实是一个静态页:
由一个网页模板和商品数据组成,电商系统每个商品上架时都会生成静态页。
完整业务流程图:
商品微服务 --消息中间件--> [商品上架交换器,商品下架交换器]
商品上架交换器 ----> [索引库上架队列,静态页上架队列]
索引库上架队列 ----> 搜索微服务 ----> 商品微服务
静态页上架队列 ----> 静态页微服务 ----> 商品微服务
搜索微服务 <--ElasticSearch--> 商品微服务
静态页微服务 <--ElasticSearch--> 商品微服务
数据库使用 MySQL 5.7.x
商品信息表:
# 创建数据库
CREATE DATABASE IF NOT EXISTS renda01 DEFAULT CHARACTER SET utf8;
# 选择使用数据库
USE renda01;
DROP TABLE IF EXISTS products;
CREATE TABLE products
(
id INT PRIMARY KEY AUTO_INCREMENT,
`name` VARCHAR(50), # 商品名称
price DOUBLE,
flag VARCHAR(2), # 上架状态
goods_desc VARCHAR(100), # 商品描述
images VARCHAR(400), # 商品图片
goods_stock INT, # 商品库存
goods_type VARCHAR(20) # 商品类型
) ENGINE = INNODB AUTO_INCREMENT = 1 DEFAULT CHARSET = utf8;
INSERT INTO products
VALUES (1, 'HUAWEO P40', 5999, '1', '华为P40 5G手机 分期 麒麟990 晨曦金 8+256GB', 'https://img14.360buyimg.com/n0/jfs/t1/133822/33/8832/135985/5f4da578E7c6efde1/2cd53a53083ab2ed.jpg', 99, '1');
基于 SpringBoot 来构造工程环境,工程模块关系如下所示:
父工程:lagou-parent
静态化微服务模块:lagou-service-page
公共模块:lagou-service-common
商品微服务模块:lagou-service-product
[静态化微服务模块,公共模块,商品微服务模块] --继承--> 父工程
静态化微服务模块 --依赖--> 公共模块 --依赖--> 商品微服务模块
使用 IDEA 创建一个 Maven 父工程 lagou-parent。
pom.xml
<packaging>pompackaging>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.1.6.RELEASEversion>
parent>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>Greenwich.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>com.alibaba.cloudgroupId>
<artifactId>spring-cloud-alibaba-dependenciesartifactId>
<version>2.1.0.RELEASEversion>
<type>pomtype>
<scope>importscope>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-webartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-loggingartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-testartifactId>
<scope>testscope>
dependency>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
<version>1.18.4version>
<scope>providedscope>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-actuatorartifactId>
dependency>
<dependency>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-devtoolsartifactId>
<optional>trueoptional>
dependency>
<dependency>
<groupId>com.sun.xml.bindgroupId>
<artifactId>jaxb-coreartifactId>
<version>2.2.11version>
dependency>
<dependency>
<groupId>javax.xml.bindgroupId>
<artifactId>jaxb-apiartifactId>
dependency>
<dependency>
<groupId>com.sun.xml.bindgroupId>
<artifactId>jaxb-implartifactId>
<version>2.2.11version>
dependency>
<dependency>
<groupId>org.glassfish.jaxbgroupId>
<artifactId>jaxb-runtimeartifactId>
<version>2.2.10-b140310.1920version>
dependency>
<dependency>
<groupId>javax.activationgroupId>
<artifactId>activationartifactId>
<version>1.1.1version>
dependency>
dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.pluginsgroupId>
<artifactId>maven-compiler-pluginartifactId>
<configuration>
<source>11source>
<target>11target>
<encoding>utf-8encoding>
configuration>
plugin>
<plugin>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-maven-pluginartifactId>
<executions>
<execution>
<goals>
<goal>repackagegoal>
goals>
execution>
executions>
plugin>
plugins>
build>
使用 IDEA 在 lagou-parent
下创建一个子工程 lagou-service-common
mybatis-plus
<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>lagou-parentartifactId>
<groupId>com.rendagroupId>
<version>1.0-SNAPSHOTversion>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>lagou-service-commonartifactId>
<dependencies>
<dependency>
<groupId>com.baomidougroupId>
<artifactId>mybatis-plus-boot-starterartifactId>
<version>3.3.2version>
dependency>
<dependency>
<groupId>javax.persistencegroupId>
<artifactId>javax.persistence-apiartifactId>
<version>2.2version>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<scope>runtimescope>
dependency>
dependencies>
project>
使用 IDEA 连接 MySQL 数据库,然后选中数据库 renda01
下的表 products
,右键 -> Scripted Extensions
-> Generate POJOs.groovy
-> 自动生成 products 表的实体类。
编辑实体类,加入 Lombok 的注解。
com.renda.common.pojo.Products
package com.renda.common.pojo;
import lombok.Data;
import javax.persistence.Id;
import javax.persistence.Table;
@Data
@Table(name = "products")
public class Products {
@Id
private long id;
private String name;
private double price;
private String flag;
private String goodsDesc;
private String images;
private long goodsStock;
private String goodsType;
}
商品微服务是服务提供者,页面静态化微服务是服务的消费者。
使用 IDEA 在 lagou-parent
下创建一个子工程 lagou-service-product
。
1)在商品微服务的 pom 文件中,引入公共组件坐标:
<dependency>
<groupId>com.rendagroupId>
<artifactId>lagou-service-commonartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
2)在 src\main\resources\application.yml
文件中配置端口、应用名、数据库连接等信息:
server:
# 微服务的集群环境中,通常会为每一个微服务叠加。
port: 9000
spring:
application:
name: lagou-service-product
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/renda01?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: password
3)Mapper 接口开发:
com.renda.product.mapper.ProductMapper
package com.renda.product.mapper;
import com.baomidou.mybatisplus.core.mapper.BaseMapper;
import com.renda.common.pojo.Products;
/**
* 现在使用的 Mybatis-plus 组件,
* 该组件是 Mybatis 的加强版;
* 能够与 SpringBoot 进行非常友好的整合,
* 对比 Mybatis 框架只有使用便捷的改变,
* 没有具体功能的改变。
* 具体使用:让具体的 Mapper 接口继承 BaseMapper 即可
*
* @author Renda Zhang
* @since 2020-11-01 1:40
*/
public interface ProductMapper extends BaseMapper<Products> {
}
4)Service 层开发:
com.renda.product.service.ProductService
public interface ProductService {
/**
* 通过商品 ID 查询商品信息
*/
Products queryById(Integer id);
}
com.renda.product.service.impl.ProductServiceImpl
@Service
public class ProductServiceImpl implements ProductService {
@SuppressWarnings("SpringJavaInjectionPointsAutowiringInspection")
@Autowired
private ProductMapper productMapper;
@Override
public Products queryById(Integer id) {
return productMapper.selectById(id);
}
}
5)Controller 层开发:
com.renda.product.controller.ProductController
@RestController
@RequestMapping("/product")
public class ProductController {
@Autowired
private ProductService productService;
@GetMapping("/query/{id}")
public Products queryById(@PathVariable Integer id){
return productService.queryById(id);
}
}
6)启动类:
com.renda.product.ProductApplication
@SpringBootApplication
@MapperScan("com.renda.product.mapper")
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class, args);
}
}
7)使用 Postman 测试:
GET http://localhost:9000/product/query/1
使用 IDEA 在 lagou-parent
下创建一个子工程 lagou-service-page
。
1) 在 pom 文件中,引入公共组件依赖:
<dependency>
<groupId>com.rendagroupId>
<artifactId>lagou-service-commonartifactId>
<version>1.0-SNAPSHOTversion>
dependency>
2)在 src\main\resources\application.yml 文件中配置端口、应用名、数据库连接等信息:
server:
# 后期该微服务多实例,端口从 9100 递增(10 个以内)
port: 9100
Spring:
application:
name: lagou-service-page
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://localhost:3306/renda01?useUnicode=true&characterEncoding=utf8&serverTimezone=UTC
username: root
password: password
3)编写 PageController,在 PageController 中调用商品微服务对应的 URL:
com.renda.page.controller.PageController
@RestController
@RequestMapping("/page")
public class PageController {
@Autowired
RestTemplate restTemplate;
@GetMapping("/getProduct/{id}")
public Products getProduct(@PathVariable Integer id) {
// 发送 HTTP 请求到商品微服务,获取 id 所对应的 products 对象
String url = "http://localhost:9000/product/query/";
return restTemplate.getForObject(url + id, Products.class);
}
}
4)编写启动类,注入 RestTemplate:
com.renda.page.PageApplication
@SpringBootApplication
public class PageApplication {
public static void main(String[] args) {
SpringApplication.run(PageApplication.class,args);
}
// 向容器中注入一个 RestTemplate,封装了 HttpClient
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
5)使用 Postman 测试:
GET http://localhost:9100/page/getProduct/1
在页面静态化微服务中使用 RestTemplate 调用商品微服务的商品状态接口时(Restful API 接口),在微服务分布式集群环境下会存在的问题:
这些问题,就需要微服务架构来解决:
想了解更多,欢迎关注我的微信公众号:Renda_Zhang