当前位置: 首页 > news >正文

Spring Cloud:概述,服务注册和服务发现,多机部署和负载均衡

什么是微服务

        就是将一个大型的应用程序拆分成多而小的独立的服务模块,每个服务模块围绕某个业务功能建立,具有独立的数据库,服务栈,并通过轻量级的通信协议进行交互。

单体架构

        就是将所有的业务和功能都打包在一个jar包中,这就是单体架构。

单体架构的优点:构建简单,部署简单,一个项目包括了多个功能,省去了不同项目交互调用的麻烦,

单体架构的缺点:由于网站用户越来越多,需求也越来越多,功能需求也越来越多,导致后端的压力越来越大,负载越来越高,一个很小的问题,就会引起很大的连锁反应,冗余性太高。

集群和分布式

        集群:是将一个系统部署到多个服务器上,每个服务器都能提供系统的所有服务,多个服务器通过负载均衡调度完成工作,每个服务器称为集群的节点。

        分布式:将一个系统拆分成多个子系统,多个子系统部署到多个服务器上,多个服务器上的子系统协同完成工作。

集群是多个计算机在做相同的事,分布式是多个计算机在不同的事情。

微服务架构

        就是每个服务只负责一种特定的业务功能,每个服务独立构建,测试部署,互不干扰,可用不同的技术栈。

Spring-Cloud

Spring-Cloud就是微服务的一种解决方案

单项依赖

        微服务之间需要做到单项依赖,严禁循环依赖,双向依赖。

DependencyManagement和Dependencies

dependencies

将所依赖的jar直接加入到项目中,子项目也会继承该依赖。

DependencyManagement

只是申明依赖,并没有jar包的引入,如果子项目需要用到相关的依赖,需要自己引入

  <properties><maven.compiler.source>17</maven.compiler.source><maven.compiler.target>17</maven.compiler.target><java.version>17</java.version><mybatis.version>2.2.0</mybatis.version> <!-- 使用已知的兼容版本 --><mysql.version>8.0.33</mysql.version><spring-cloud.version>2022.0.3</spring-cloud.version></properties>
<dependencyManagement><dependencies><dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-dependencies</artifactId><version>${spring-cloud.version}</version><type>pom</type><scope>import</scope></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter</artifactId><version>${mybatis.version}</version> <!-- 采用最新兼容版本 --></dependency><dependency><groupId>com.mysql</groupId><artifactId>mysql-connector-j</artifactId><version>${mysql.version}</version></dependency><dependency><groupId>org.mybatis.spring.boot</groupId><artifactId>mybatis-spring-boot-starter-test</artifactId><version>${mybatis.version}</version><scope>test</scope></dependency></dependencies></dependencyManagement>

在创建子项目的时候,注意pom文件申明项目的依赖和构建插件

简单创建好父子工程

来进行远程调用

根据订单查询订单信息时,根据订单里面的产品Id,获取产品的详细信息

可以采用RestTemplate

RestTemplate 是 Spring 提供的用于 同步 HTTP 请求的客户端工具类,它可以方便地发送 HTTP 请求并接收响应,支持 GET、POST、PUT、DELETE 等多种请求方法

定义RestTemplate

 @Configurationpublic class BeanConfig {@Beanpublic RestTemplate restTemplate(){return new RestTemplate();}}
@Slf4j
@Service
public class OrderService {@Autowiredprivate OrderMapper orderMapper;@Autowiredprivate RestTemplate restTemplate;public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);String url = "http://127.0.0.1:9090/product/"+orderInfo.getProductId();ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}
}

测试一下

但是rul是写死的,如果要是修改IP,就得修改代码

注册中心

CPA理论

一致性:CPA理论中的一致性,指的是强一致性,所有节点在同一时间既有相同的数据。

可用性:保证每个请求都有响应。

分区容错性:当出现网络分区后,系统仍然能对外提供服务。

这三个基本需求,不能一次性全部满足,最多只能满足两个,CA或者CP架构。

Eureka

        Eureka是Netflix开发的基于REST的服务发现框架,主要⽤于服务注册,管理,负载均衡和服务故障 转移,是常见的注册中心。

EurekaServer的搭建

        EurekaServer是一个独立的微服务

注意:要引入eureka-server依赖

 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-netflix-eureka-server</artifactId></dependency>

构建插件

build><plugins><plugin><groupId>org.springframework.boot</groupId><artifactId>spring-boot-maven-plugin</artifactId><configuration><mainClass>org.example.eurekaserver.EurekaServerApplication</mainClass></configuration></plugin></plugins></build>

注意在启动类上添加@EnableEurekaServer注解,用来开启eureka注册中心

@EnableEurekaServer
@SpringBootApplication
public class EurekaServerApplication {public static void main(String[] args) {SpringApplication.run(EurekaServerApplication.class,args);}
}

配置文件

server:port: 10010
spring:application:name: eureka-server
eureka:instance:hostname: localhostclient:fetch-registry: false # 表示是否从Eureka Server获取注册信息,默认为true.因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,这里设置为falseregister-with-eureka: false # 表示是否将自己注册到Eureka Server,默认为true.由于当前应用就是Eureka Server,故而设置为false.service-url:# 设置Eureka Server的地址,查询服务和注册服务都需要依赖这个地址defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
logging:pattern:console: '%d{MM-dd HH:mm:ss.SSS} %c %M %L [%thread] %m%n'

启动服务

 在远程调⽤时,从eureka-server拉取product-service的服务信息,url则不会被写死

@Slf4j
@Service
public class OrderService {  @Autowiredprivate DiscoveryClient discoveryClient;public OrderInfo selectOrderById(Integer orderId){OrderInfo orderInfo = orderMapper.selectOrderById(orderId);//从Eureka中获取服务列表List<ServiceInstance> instances = discoveryClient.getInstances("product-service");String uri = instances.get(0).getUri().toString();String url = uri+"/product/"+orderInfo.getProductId();log.info("远程调用url:{}", url);ProductInfo productInfo = restTemplate.getForObject(url, ProductInfo.class);orderInfo.setProductInfo(productInfo);return orderInfo;}

负载均衡

 这行代码是获得了第一个服务实例,但是如果有多个服务实例呢?

EurekaServiceInstance instance = (EurekaServiceInstance) instances.get(0);

在创建几个实例后我们发现访问的都是同一台机器,其它的并没有进行访问。

修改代码,使其轮流访问

int index = atomicInteger.getAndIncrement() % instances.size();
    public OrderDetail selectOrderById(Integer orderId){OrderDetail orderDetail = orderMapper.selectOrderById(orderId);
//        String url="http://localhost:9090/product/"+orderDetail.getProductId();
//        if (instances == null || instances.isEmpty()) {
//            log.warn("No available instances for product-service");
//            throw new IllegalStateException("No available instances for product-service");
//        }List<ServiceInstance> instances= discoveryClient.getInstances("product-service");int index=count.getAndIncrement() % instances.size();URI uri = instances.get(index).getUri();String url=uri+"/product/"+orderDetail.getProductId();log.info("url:{}",url);ProductDetail productDetail = restTemplate.getForObject(url, ProductDetail.class);orderDetail.setProductDetail(productDetail);return orderDetail;}

 

请求被均衡的分配在了不同的实例上,这就是负载均衡

负载均衡:当服务流量增⼤时,通常会采⽤增加机器的⽅式进⾏扩容,负载均衡就是⽤来在多个机器或者其他资源 中,按照⼀定的规则合理分配负载

SpringCloudLoadBalancer

SpringCloudLoadBalancer这个组件是用来实现客户端的负载均衡

添加 @LoadBalanced 注解

@LoadBalancerClient(name = "product-service",configuration = CustomLoadBalancerConfiguration.class)
@Configuration
public class BeanConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate(){return new RestTemplate();}
}

修改IP端⼝号为服务名称

public OrderDetail selectOrderById(Integer orderId){OrderDetail orderDetail = orderMapper.selectOrderById(orderId);String url="http://product-service/product/"+orderDetail.getProductId();log.info("url:{}",url);ProductDetail productDetail = restTemplate.getForObject(url, ProductDetail.class);orderDetail.setProductDetail(productDetail);return orderDetail;}

负载均衡策略

        负载均衡策略是一种思想,有轮询和随机选择两种,就是字面意思。

⾃定义负载均衡策略

//负载均衡策略
public class CustomLoadBalancerConfiguration {@BeanReactorLoadBalancer<ServiceInstance> randomLoadBalancer(Environment environment,LoadBalancerClientFactory loadBalancerClientFactory) {String name = environment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);return new RandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name, ServiceInstanceListSupplier.class),name);}
}

使⽤@LoadBalancerClient或@LoadBalancerClients注解,可以对不同的服务提供⽅配置不同的客⼾端负载均衡算法策略

name:对哪个服务生效

configuration:在这写负载均衡策略,用哪个负载均衡策略实现

 

希望能对大家有所帮助!!!! 

http://www.xdnf.cn/news/334513.html

相关文章:

  • 二本计算机,毕业=失业?
  • 【Rust】结构体
  • 【算法学习】递归、搜索与回溯算法(二)
  • 计算机网络:深入分析三层交换机硬件转发表生成过程
  • 为了摸鱼和吃瓜,我开发了一个网站
  • 酒店客房拖鞋材质款式多样,对顾客入住感受影响大
  • 面试实践AND面经热点题目总结
  • 紫禁城多语言海外投资理财返利源码带前端uniapp纯工程文件
  • C++ Primer (第五版)-第十四章重载运算与类型转换
  • 雷军「去执行化」与小米汽车更名:一场关乎安全与战略的双向奔赴|创客匠人热点评述
  • 软件工程之需求分析涉及的图与工具
  • V 型球阀:多材质多驱动,精准适配复杂严苛工况-耀圣
  • 开源照片管理系统PhotoPrism的容器化部署与远程管理配置
  • 【electron+vue】常见功能之——调用打开/关闭系统软键盘,解决打包后键盘无法关闭问题
  • Inno Setup专业打包指南:从基础到高级应用
  • 没有Mac,我是怎么上传IPA到App Store的?
  • maven如何搭建自己的私服(LINUX版)?
  • 【Linux修炼手册】Linux开发工具的使用(一):yum与vim
  • 网易游戏 Flink 云原生实践
  • OrangePi Zero 3学习笔记(Android篇)3 - 串口
  • Qt实现车载多媒体项目,包含天气、音乐、视频、地图、五子棋功能模块,免费下载源文件!
  • Linux/AndroidOS中进程间的通信线程间的同步 - 消息队列
  • nputop:交互式 Ascend NPU 进程查看器(nvitop昇腾版)
  • 视觉图像处理及多模态融合初探
  • MyBatis(进阶)(xml标签)
  • 代码随想录算法训练营第三十七天-2|动态规划part2
  • [5-2] 对射式红外传感器计次旋转编码器计次 江协科技学习笔记(38个知识点)
  • 服务器数据恢复—Linux操作系统服务器意外断电导致部分文件丢失的数据恢复
  • 力扣刷题Day 41:除自身以外数组的乘积(238)
  • 【Linux】Linux工具(1)