SpringCloud-Study
SpringCloud-Study
一、微服务简介
1.单体架构和分布式架构
单体架构
分布式架构
分布式架构的问题
解决方案
小结
2.微服务
微服务技术
微服技术对比
3.SpringCloud
SpringCloud官网:https://spring.io/projects/spring-cloud
SpringCloud和SpringBoot版本兼容对照表
4.服务拆分
项目导入
案例1:根据订单id查询订单信息,并把用户信息一起返回
由于微服务之间数据独立(每个微服务都拥有自己的数据库,不能跨数据库进行查询),需要查询订单信息和用户信息
解决方案1:
订单信息再东单微服务中可以根据订单id来查询,用户信息则需要使用RestTemplate发起http请求来查询。最后将订单信息和用户信息组合并返回即可。
(1)创建RestTemplate对象,并注入到spring容器中
package cn.itcast.order;
import org.mybatis.spring.annotation.MapperScan;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@MapperScan("cn.itcast.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
/**
* 创建RestTemplate示例,并且注入到spring容器中
* @return
*/
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
(2)在服务消费者的service层中注入RestTemplate,通过restTemplate来发起http请求,进行远程调用user微服务查询user信息,并将查询到的user信息组合到order信息中。
package cn.itcast.order.service;
import cn.itcast.order.mapper.OrderMapper;
import cn.itcast.order.pojo.Order;
import cn.itcast.order.pojo.User;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
/**
*注入RestTemplate
*/
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
/**
* 使用RestTemplate来发起http请求,进行远程调度查询user的信息
*/
//通过RestTemplate来发起http请求,查询user的信息
//拼接远程调用的url
String url = "Http://127.0.0.1:8081/user/"+order.getUserId();
//通过RestTemplate发起http请求,查询user信息,
//返回的是json对象,但是可以通过设置指定类型的Class对象来将json对象转换成相应的java类型对象
User user = restTemplate.getForObject(url, User.class);
//将返回的user对象组合到查询到的order对象中
order.setUser(user);
// 4.返回
return order;
}
}
(3)通过order-service微服务查询订单信息,测试查询结果是否包含user信息
小结:
二、Eureka注册中心
1.服务消费者和服务提供者
2.Eureka注册中心的实现原理
解决方案1中存在问题:
Eureka注册中心如何解决以上问题:
每个微服务在启动时,都会在Eureka注册中心注册自己的信息(服务名称),并且定时向注册中心发送心跳请求,注册中心通过心跳检测机制可以将宕机的服务剔除,保证服务消费者能拉取到可使用的服务。服务消费者可以通过注册中心拉取到在注册中心注册的服务列表,获取所需的服务提供者的信息(ip、端口、接口路径、请求参数等...),再通过负载均衡算法选中某一个服务提供者,最后发送请求,进行远程调用。
小结:
3.Eureka注册中心环境搭建
搭建Eureka需要创建Eureka微服务,在工程目录中创建一个新的模块
手动搭建Eureka环境:
(1)导入Eureka的maven依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
(2)在启动类中添加@EnableEurekaServer注解
(3)配置文件
在微服务中添加application.yml配置文件,设置Eureka微服务的端口,将Eireka微服务本身注册到注册中心
server:
port: 10086 # 服务端口
spring:
application:
name: eurekaserver # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
通过idea搭建Eureka环境:
(1)创建新模块
(2)添加Eureka功能,springboot会自动添加Eureka服务端的maven依赖
(3)服务启动类上添加@EnableEurekaServer注解
package com.lqy.eurekaservice;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
@EnableEurekaServer
@SpringBootApplication
public class EurekaServiceApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaServiceApplication.class, args);
}
}
(4)添加配置application.yml文件
在微服务的application.yml配置文件文件中添加服务注册配置
server:
port: 10087 #设置Eureka微服务的端口
spring:
application:
name: EurekaService #设置微服务的名称
eureka: #配置eureka,将eureka微服务本身注册到注册中心
client:
service-url: #Eureka注册中心地址
defaultZone: http://localhost:10087/eureka
(5)在Eureka中查看注册的服务
登录Eureka的地址查看微服务受否已经注册到注册中心
eureka地址:http://localhost:10087/eureka/
4.服务注册
创建一个测试微服务
(1)在微服务的pom.xml文件中添加Eureka客户端的maven配置
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
(2)在微服务的application.yml配置文件文件中添加服务注册配置
spring:
application:
name: OrderService #设置微服务的名称
eureka: #配置eureka,将eureka微服务本身注册到注册中心
client:
service-url: #Eureka注册中心地址
defaultZone: http://localhost:10087/eureka
(3)模拟服务集群
在idea中复制springboot服务,并修改端口配置
(4)查看微服务是否已经在Eureka注册中心注册
将添加了eureka客户端的微服务启动,访问eureka注册中心,查看微服务是否已经注册成功
小结:
5.服务发现
微服务成功注册到eureka注册中心后,服务消费者拉取注册中心的服务列表,从中获取相应的服务提供者的信息。
(1)将远程调度的地址改成服务名
(2)在服务消费者启动类为RestTemplate实例中添加@LoadBalanced注解
(3)测试:通过服务消费者的查询是否获取到服务提供者的接口并查询出结果
小结:
tip:
chorm浏览器默认返回的json对象是呈单行显示的,不方便查看。
解决方案:
1.ctrl+shift+j打开浏览器的控制台,进行查看,但是需要在控制台和浏览器主页面中进行切换,比较麻烦
2.安装一款chrom浏览器插件JSONView-for-Chrome,返回的json对象可以呈树状显示:插件下载地址
参考:https://blog.csdn.net/qq_24052051/article/details/127418888
三、Ribbon-负载均衡
1.负载均衡原理
2.负载均衡策略
修改负载均衡机制的方法:
访问不同的订单时,通过默认的负载均衡机制会轮回地选择各个user-service集群
(1)修改方法一:
针对全部微服务的负载均衡机制修改。
这里修改负载均衡机制为随机,不再是轮回选择:
在服务消费者的配置类中创建IRule实例对象并注入到spring容器中。
创建order-service微服务的配置类OrderServiceConfig.java,将之前在启动类编写的RestTemplate实例对象迁移到配置类中,实现统一管理。
package cn.itcast.order.config;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
* 订单微服务配置类
*/
@Configuration
public class OrderServiceConfig {
//创建RestTemplate实例对象并注入spring容器中
/**
* 创建RestTemplate实例,并且注入到spring容器中
* @return
*/
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
//修改ribbon负载均衡机制为随机,创建一个IRule实例对象并注入spring容器中
@Bean
public IRule randomRule(){
return new RandomRule();
}
}
在order-service微服务中发送4次订单信息查询请求,发现此时负载均衡机制选择了user-service2微服务3次,选择了user-service微服务1次。实行的是随机选择,说明负载均衡机制修改成功!一般使用默认的轮回选择即可。
(2)修改方法二:
针对某个微服务的负载均衡机制修改。
在服务消费者的配置文件中添加以下配置:
UserService: #针对的服务提供者的服务名
ribbon:
NFLoadBalancerRuleClassName: com.netflix.loadbalancer.RandomRule #设置负载均衡机制为随机选择
3.懒加载和饥饿加载
1.懒加载:第一次访问时才创建LoadBalanceClient,首次访问时耗时较长
2.饥饿加载:在项目启动时就创建LoadBalanceClient,首次访问耗时不长
可以将ribbon默认的懒加载机制修改为饥饿加载
将懒加载修改为饥饿加载:
ribbon: #修改ribbon的默认懒加载为饥饿加载
eager-load:
enable: true
clients:
-UserService #可以指定多个微服务
修改为饥饿加载后,首次访问耗时降低了:
ribbon负载均衡小结:
四、Nacos
1.Nacos安装
(1)下载和安装
nacos官网地址:https://nacos.io/
选择github下载,点击release,选择相应的版本进行下载
(2)修改nacos的端口配置为8848
在安装目录下在conf目录中打开application.propertiese配置文件,将server.port修改为8848并保存。
(3)启动nacos服务
打开cmd,进入doc命令模式,进入nacos安装目录下的bin目录,执行以下命令启动nacos
(也可以在文件管理器中打开bin目录,然后再地址栏中输入cmd并回车,再执行以下命令,启动nacos)
startup.cmd -m standalone
(4)访问nacos主页
成功启动nacos后,再浏览器中访问nacos主页,登录名和密码默认都是nacos
主页地址:http://localhost:8848/nacos/
2.Nacos快速入门
(1)引入nacos依赖
1)在父工程中添加nacos依赖
<!--添加spring-cloud-alibaba依赖-->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.2.5.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
2)在微服务的pom.xml文件中要导入nacos-discovery依赖
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId>
</dependency>
此处:因为在order-service微服务中导入的依赖包含了版本信息,结果导致远程调度失败!不能查询到user信息,即在nacos注册中心中没有拉取到相应的userservice微服务的信息,产生bug!需要查询该问题
(2)在微服务的配置文件application.yml中修改为nacos的地址
如果之前使用eureka则需要将eureka的地址信息注释掉,修改为nacos的地址信息
spring: #spring配置
application:
name: UserService #设置微服务名称
cloud:
nacos:
server-addr: 127.0.0.1:8848 #nacos服务地址
(3)启动服务,访问nacos主页,查看服务是否已经注册到nacos注册中心
小结:
3.Nacos的服务多级存储模型
nacos的分级存储:
服务-->集群-->实例
(1)在微服务的application.propertises配置文件中添加集群配置(nacos的cluster-name)
先启动user-service1和user-service2,再修改配置中的集群名称为SH,再启动user-service3
(2)登录nacos主页查看服务注册情况:
点击详情查看服务的注册具体情况:
4.NacosRule负载均衡
5.Nacos服务实例的权重设置
在nacos主页中可以直接设置服务的权重,服务权重设置为0时,服务不会被访问,可以在服务升级时将服务的权重设置为0.
6.Nacos环境隔离
(1)新建namespace命名空间
(2)填写namespace的信息(namespaced的id不填会自动随机生成)
(3)在服务消费者的配置文件中添加nacos的namespace的配置(填写namespace的Id)
(4)查看服务注册详情,发现生成了public和dev两个环境
此时重启order-service微服务时,发现order-service在dev环境下,对order进行查询时,会报错。说明不同环境的服务时不能进行访问的,实现了环境隔离。
小结:
7.Nacos和Eureka的对比
(1)nacos注册中心
nacos的临时实例:会向nacos定时(默认30秒发送一次)发送心跳检测,汇报服务的健康情况
nacos的非临时实例:不会向nacos发送心跳检测,但是nacos会主动询问其健康状态
默认都是临时实例,可以修改配置,将实例修改为非临时实例
cloud:
nacos:
server-addr: 127.0.0.1:8848 #配置nacos注册中心的地址(ip地址和端口号)
discovery:
cluster-name: BJ #配置微服务所属的集群名称
namespace: b99c9427-234e-4c49-8fde-6e88f4e367d5 #配置nacos的namespace的Id dev开发环境
ephemeral: false #false表示非临时实例
s
(2)eureka注册中心
eureka注册中心不会及逆行消息推送,即在服务宕机时,nacos会主动将信息push给服务消费者,而使用eureka的服务消费者只能时定时pull注册中心的服务列表。因此,相比之下nacos注册中心的服务列表缓存的消息更新会更及时。
小结:
8.nacos管理配置
(1)nacos实现配置管理
1)新建服务的配置管理
2)填写服务的配置信息
(2)微服务配置拉取nacos的配置信息原理分析
在读取本地配置信息前,会先读取nacos上的配置信息,但是nacos的配置信息如果放置在application.yml文件中就不能优先读取nacos的配置信息,这是需要创建一个bootstrap.yml配置文件,将nacos的地址信息配置在这个bootstrap.yml文件中。
- 导入依赖
- 创建bootstrap.yml配置文件
测试:
编写测试代码:
启动微服务,访问编写的页面,查看是否可以查看到当前时间,并且安装配置的时间格式进行显示。