单体架构
简单方便,高度耦合,扩展性差,适合小型项目。例如:学生管理系统
分布式架构
根据业务对功能经行拆分 每个业务功能独立开发优点: 降低耦合 有利于服务的升级和拓展缺点:服务调用关系复杂松耦合,扩展性好,但架构复杂,难度大。适合大型互联网项目,例如:京东、淘宝
什么是微服务?
微服务是一种经过良好设计的分布式架构方案架构特点- 单一职责:微服务拆分粒度更小,每一个服务都对应唯一的业务能力,做到单一职责- 自治:团队独立、技术独立、数据独立,独立部署和交付- 面向服务:服务提供统一标准的接口,与语言和技术无关- 隔离性强:服务调用做好隔离、容错、降级,避免出现级联问题①优点:拆分粒度更小、服务更独立、耦合度更低②缺点:架构非常复杂,运维、监控、部署难度提高
如何实现服务间调用的?
在服务的启动类中,注册RestTemplate实例:修改模块中的service层类中的方法:
什么是SpringCloud?
SpringCloud是目前国内使用最广泛的微服务框架。官网地址:https://spring.io/projects/spring-cloud。
注册中心高可用
eureka注册中心
1. 创建eureka-secvice服务模块2. 引入SpringCloud为eureka提供依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>3. cureka-scrvice模块编写启动类@SpringBootApplication //此类为启动类@EnableEurekaServer //eureka注册中心启动 注解4. 编写application.yml配置文件server:port: 10086spring:application:name: eureka-servereureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka5. 启动服务浏览器访问:http://127.0.0.1:10086
服务注册
1. 添加依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>2. 添加application.yml配置文件spring:application:name: userservice(注册服务的模块名)eureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka3. 查看eureka-server管理页面:
服务发现
1. 引入依赖<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-client</artifactId></dependency>2. 添加application.yml配置文件spring:application:name: orderserviceeureka:client:service-url:defaultZone: http://127.0.0.1:10086/eureka3. 服务拉取和负载均衡最后,我们要去eureka-server中拉取user-service服务的实例列表,并且实现负载均衡。不过这些动作不用我们去做,只需要添加一些注解即可。在order-service的OrderApplication中,给RestTemplate这个Bean添加一个@LoadBalanced注解:修改order-service服务中的cn.itcast.order.service包下的OrderService类中的queryOrderById方法。修改访问的url路径,用服务名代替ip、端口:
Ribbon负载均衡
SpringCloud底层其实是利用了一个名为Ribbon的组件,来实现负载均衡功能的。
负载均衡策略
负载均衡的规则都定义在IRule接口中,而IRule有很多不同的实现类 不同规则的含义如下:
| 内置负载均衡规则类 | 规则描述 |
|---|---|
| RoundRobinRule | 简单轮询服务列表来选择服务器。 |
| AvailabilityFilteringRule | 对以下两种服务器进行忽略: (1)在默认情况下,这台服务器如果3次连接失败,这台服务器就会被设置为“短路”状态。短路状态将持续30秒,如果再次连接失败,短路的持续时间就会几何级地增加。 (2)并发数过高的服务器。如果一个服务器的并发连接数过高,配置了AvailabilityFilteringRule规则的客户端也会将其忽略。并发连接数的上限,可以由客户端的..ActiveConnectionsLimit属性进行配置。 |
| WeightedResponseTimeRule | 为每一个服务器赋予一个权重值。服务器响应时间越长,这个服务器的权重就越小。这个规则会随机选择服务器,这个权重值会影响服务器的选择。 |
| ZoneAvoidanceRule | 以区域可用的服务器为基础进行服务器的选择。使用Zone对服务器进行分类,这个Zone可以理解为一个机房、一个机架等。而后再对Zone内的多个服务做轮询。 |
| BestAvailableRule | 忽略那些短路的服务器,并选择并发数较低的服务器。 |
| RandomRule | 随机选择一个可用的服务器。 |
| RetryRule | 重试机制的选择逻辑 |
默认的实现就是ZoneAvoidanceRule,是一种轮询方案
自定义负载均衡策略
两种方式1.代码方式@Beanpublic IRule randomRule(){return new RandomRule(); //负载均衡策略 随机选择一个可用的服务器。}2.application配置文件方式userservice: # 给某个微服务配置负载均衡规则,这里是userservice服务ribbon:NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule# 负载均衡规则
Nacos注册中心
服务注册到nacos注册中心
1. 引入依赖1.1在父工程的pom文件中的<dependencyManagement>中引入依赖:<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>1.2然后在user-service和order-service中的pom文件中引入nacos-discovery依赖:<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId></dependency>2. application配置nacos地址spring:cloud:nacos:server-addr: localhost:88483. 重启微服务 登录nacos管理页面注意:不要忘了注释掉eureka的依赖和配置。
权重配置
实际部署中会出现这样的场景:
服务器设备性能有差异,部分实例所在机器性能较好,另一些较差,我们希望性能好的机器承担更多的用户请求。
但默认情况下NacosRule是同集群内随机挑选,不会考虑机器的性能问题。
因此,Nacos提供了权重配置来控制访问频率,权重越大则访问频率越高。
在nacos控制台,找到user-service的实例列表,点击编辑,即可修改权重:
在弹出的编辑窗口,修改权重:
集群
修改user-service的application.yml文件,添加集群配置:spring:cloud:nacos:server-addr: localhost:8848discovery:cluster-name: HZ # 集群名称
环境隔离
nacos和eureka的区别?
Nacos的服务实例分为两种l类型:
- 临时实例:如果实例宕机超过一定时间,会从服务列表剔除,默认的类型。
- 非临时实例:如果实例宕机,不会从服务列表剔除,也可以叫永久实例。
配置一个服务实例为永久实例:
spring:cloud:nacos:discovery:ephemeral: false # 设置为非临时实例
Nacos与eureka的共同点
- 都支持服务注册和服务拉取
- 都支持服务提供者心跳方式做健康检测
Nacos与Eureka的区别
- Nacos支持服务端主动检测提供者状态:临时实例采用心跳模式,非临时实例采用主动检测模式
- 临时实例心跳不正常会被剔除,非临时实例则不会被剔除
- Nacos支持服务列表变更的消息推送模式,服务列表更新更及时
- Nacos集群默认采用AP方式,当集群中存在非临时实例时,采用CP模式;Eureka采用AP方式
微服务、springboot、springcloud有何联系?
Nacos配置中心
从微服务拉取配置
1.引入依赖
首先,在user-service服务中,引入nacos-config的客户端依赖:<!--nacos配置管理依赖--><dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId></dependency>
2.添加bootstrap.yaml
然后,在user-service中添加一个bootstrap.yaml文件,内容如下:
spring:application:name: userservice # 服务名称profiles:active: dev #开发环境,这里是devcloud:nacos:server-addr: localhost:8848 # Nacos地址config:file-extension: yaml # 文件后缀名
热更新
方式一
在@Value注入的变量所在类上添加注解@RefreshScope:
方式二
使用@ConfigurationProperties注解代替@Value注解。在user-service服务中,添加一个类,读取patterrn.dateformat属性:在UserController中使用这个类代替@Value:
Feign的远程调用
替代RestTemplate
1.引入依赖
我们在order-service服务的pom文件中引入feign的依赖:
<dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-openfeign</artifactId></dependency>
2.添加注解
在order-service的启动类添加注解开启Feign的功能:
@EnableFeignClientsEnable 启用feignClients 客户
3.编写Feign客户端
在order-service中新建一个接口
package cn.itcast.order.client;import cn.itcast.order.pojo.User;import org.springframework.cloud.openfeign.FeignClient;import org.springframework.web.bind.annotation.GetMapping;import org.springframework.web.bind.annotation.PathVariable;@FeignClient("userservice")public interface UserClient {@GetMapping("/user/{id}")User findById(@PathVariable("id") Long id);}
4.测试
修改order-service中的OrderService类中的queryOrderById方法,使用Feign客户端代替RestTemplate:
使用Feign的步骤:
① 引入依赖
② 添加@EnableFeignClients注解
③ 编写FeignClient接口
④ 使用FeignClient中定义的方法代替RestTemplate
自定义配置
Feign可以支持很多的自定义配置,如下表所示:
| 类型 | 作用 | 说明 |
|---|---|---|
| feign.Logger.Level | 修改日志级别 | 包含四种不同的级别:NONE、BASIC、HEADERS、FULL |
| feign.codec.Decoder | 响应结果的解析器 | http远程调用的结果做解析,例如解析json字符串为java对象 |
| feign.codec.Encoder | 请求参数编码 | 将请求参数编码,便于通过http请求发送 |
| feign. Contract | 支持的注解格式 | 默认是SpringMVC的注解 |
| feign. Retryer | 失败重试机制 | 请求失败的重试机制,默认是没有,不过会使用Ribbon的重试 |
日志
1.配置文件
基于配置文件修改feign的日志级别可以针对单个服务:
feign:client:config:userservice: # 针对某个微服务的配置loggerLevel: FULL # 日志级别
也可以针对所有服务
feign:client:config:userservice: # 针对某个微服务的配置loggerLevel: FULL # 日志级别
而日志的级别分为四种:
- NONE:不记录任何日志信息,这是默认值。
- BASIC:仅记录请求的方法,URL以及响应状态码和执行时间
- HEADERS:在BASIC的基础上,额外记录了请求和响应的头信息
- FULL:记录所有请求和响应的明细,包括头信息、请求体、元数据。
2.java代码
也可以基于Java代码来修改日志级别,先声明一个类,然后声明一个Logger.Level的对象:
public class DefaultFeignConfiguration {@Beanpublic Logger.Level feignLogLevel(){return Logger.Level.BASIC; // 日志级别为BASIC}}
如果要全局生效,将其放到启动类的@EnableFeignClients这个注解中:
@EnableFeignClients(defaultConfiguration = DefaultFeignConfiguration .class)
如果是局部生效,则把它放到对应的@FeignClient这个注解中:
@FeignClient(value = "userservice", configuration = DefaultFeignConfiguration .class)
