微服务架构中的负载均衡与服务注册中心(Nacos)

1. 负载均衡:解决实际业务问题

1.1 业务场景思考

想象一个电子商务平台的微服务架构。我们有一个订单服务和多个用户服务实例。当订单服务需要调用用户服务时,它如何选择具体调用哪一台用户服务器?这就是负载均衡要解决的核心问题。

1.2 常用负载均衡算法及其业务影响

1.2.1 轮询(Round Robin)
  • 原理:请求依次分配给每个服务器。
  • 业务影响
    • 优点:实现简单,在服务器性能相近的情况下能达到较好的负载平衡。
    • 缺点:不考虑服务器当前负载,可能导致某些正在处理复杂请求的服务器过载。
1.2.2 加权轮询(Weighted Round Robin)
  • 原理:根据服务器的性能赋予权重,性能较好的服务器处理更多请求。
  • 业务场景:假设用户服务有3台服务器:
    • 8080端口:权重1
    • 8081端口:权重1
    • 8082端口:权重2(性能更高)
  • 请求分配示例
    1. 用户1请求 → 8080
    2. 用户2请求 → 8081
    3. 用户3请求 → 8082
    4. 用户4请求 → 8082
  • 业务影响
    • 优点:可以根据服务器实际性能分配负载,提高资源利用率。
    • 缺点:需要手动配置和调整权重,不能自动适应服务器状态变化。
1.2.3 最小连接(Least Connections)
  • 原理:将新请求分配给当前连接数最少的服务器。
  • 业务影响
    • 优点:能够动态调整,避免将请求分配给已经负载较重的服务器。
    • 缺点:可能不适用于长连接服务,因为连接数不一定反映真实负载。
1.2.4 哈希(Hash)
  • 原理:根据请求的某个特征(如用户ID)计算哈希值,将相同哈希值的请求发送到同一服务器。
  • 业务场景
    • 用户A的所有请求都发送到8080端口的服务器
    • 用户B的所有请求都发送到8081端口的服务器
  • 业务影响
    • 优点:可以实现会话保持,有利于缓存利用和状态管理。
    • 缺点:可能导致负载不均衡,特别是在有"热点"用户的情况下。
1.2.5 随机(Random)
  • 原理:随机选择一个服务器处理请求。
  • 业务影响
    • 优点:实现简单,在请求量很大时能达到类似轮询的效果。
    • 缺点:短期内可能导致负载不均衡。

1.3 负载均衡的实际应用

以下是一个简单的随机负载均衡算法的Java实现示例,可以用于订单服务调用用户服务:

public class UserServiceLoadBalancer {private String[] userServiceUrls;private Random random;public UserServiceLoadBalancer(String[] userServiceUrls) {this.userServiceUrls = userServiceUrls;this.random = new Random();}public String getRandomUserService() {int index = random.nextInt(userServiceUrls.length);return userServiceUrls[index];}
}// 使用示例
public class OrderService {private UserServiceLoadBalancer loadBalancer;public OrderService() {String[] userServices = {"http://localhost:8080/user/info","http://localhost:8081/user/info","http://localhost:8082/user/info"};this.loadBalancer = new UserServiceLoadBalancer(userServices);}public void processOrder(int userId) {String userServiceUrl = loadBalancer.getRandomUserService();// 使用选中的用户服务URL处理订单System.out.println("Processing order for user " + userId + " using service: " + userServiceUrl);}
}

2. 服务注册与发现:动态管理服务实例

2.1 业务场景思考

在一个快速发展的电商平台中,用户服务可能需要经常扩容或者进行维护。如果订单服务中硬编码了用户服务的地址,每次用户服务发生变化都需要修改订单服务的代码并重新部署,这显然是不可接受的。

2.2 注册中心的核心业务流程

  1. 服务注册

    • 用户服务启动时,向注册中心注册自己的信息(如服务名、URL、端口号)。
    • 示例:用户服务启动时调用注册中心的注册接口。
  2. 状态同步

    • 用户服务定期向注册中心发送心跳,更新自己的状态。
    • 如果注册中心在一定时间内没有收到心跳,会将该服务标记为不可用。
  3. 服务发现

    • 订单服务需要调用用户服务时,先从注册中心获取可用的用户服务列表。
    • 然后使用负载均衡算法选择一个具体的服务实例进行调用。
  4. 服务下线

    • 当用户服务需要下线维护时,主动向注册中心发送下线请求。
    • 注册中心将该服务从可用列表中移除,确保不会有新的请求被路由到该服务。

2.3 注册中心的数据结构示例

{"userService": [{"url": "localhost", "port": 8080, "lastHeartbeat": "2024-09-10 10:58:00"},{"url": "localhost", "port": 8081, "lastHeartbeat": "2024-09-10 10:59:00"},{"url": "localhost", "port": 8082, "lastHeartbeat": "2024-09-10 10:59:30"}]
}

2.4 使用Nacos作为注册中心

Nacos是一个功能强大的注册中心和配置管理平台。以下是在Spring Boot项目中使用Nacos的基本步骤:

  1. 添加依赖
<dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId><version>2021.1</version>
</dependency>
  1. 配置Nacos服务器地址

application.properties中添加:

spring.cloud.nacos.discovery.server-addr=127.0.0.1:8848
spring.application.name=user-service

服务启动后的访问地址:http://localhost:8848/nacos/
类似:
在这里插入图片描述

  1. 启用服务注册与发现

在主类上添加@EnableDiscoveryClient注解:

@SpringBootApplication
@EnableDiscoveryClient
public class UserServiceApplication {public static void main(String[] args) {SpringApplication.run(UserServiceApplication.class, args);}
}
  1. 服务调用

在订单服务中使用@LoadBalanced注解和RestTemplate进行服务调用:

@Configuration
public class RestTemplateConfig {@Bean@LoadBalancedpublic RestTemplate restTemplate() {return new RestTemplate();}
}@Service
public class OrderService {@Autowiredprivate RestTemplate restTemplate;public void processOrder(int userId) {UserInfo userInfo = restTemplate.getForObject("http://user-service/user/info/" + userId, UserInfo.class);// 处理订单逻辑}
}

3. 实际业务中的最佳实践

  1. 选择合适的负载均衡策略

    • 对于无状态服务,可以使用轮询或加权轮询。
    • 对于有状态服务或需要会话保持的场景,考虑使用哈希策略。
  2. 实现智能健康检查

    • 不仅检查服务是否在线,还要检查服务的响应时间和错误率。
    • 当发现服务性能下降时,及时将其从可用列表中移除。
  3. 实现优雅的服务下线

    • 在服务下线前,先停止接收新请求,等待当前请求处理完毕后再下线。
  4. 采用蓝绿部署或金丝雀发布

    • 使用注册中心和负载均衡,可以方便地实现蓝绿部署或金丝雀发布,降低发布风险。
  5. 监控和告警

    • 对服务的健康状态、负载情况进行实时监控。
    • 设置合理的告警阈值,及时发现和解决问题。

结论

通过合理使用负载均衡和注册中心,我们可以构建一个更加健壮、可扩展的微服务架构。这不仅提高了系统的可用性,还大大增强了运维的灵活性。在实际业务中,要根据具体的场景选择合适的策略,并持续优化以应对不断变化的业务需求。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.xdnf.cn/news/145557.html

如若内容造成侵权/违法违规/事实不符,请联系一条长河网进行投诉反馈,一经查实,立即删除!

相关文章

主流卷积神经网络CNN总结

ResNet&#xff08;2015&#xff09;残差神经网络 残差结构 ResNet50具体卷积结构图 ResNeXt&#xff08;2016&#xff09;加入了分组卷积的思想&#xff0c;将原ResNet网络中的block替换成由group分组的block&#xff0c;两者得到的feature map一致&#xff0c;只是参数量更少…

《微软飞行模拟2024》储存空间需求仅不到前作的1/5

根据微软在最新一期 Xbox Wire 中的介绍&#xff0c;将于今年11 月登陆 Xbox Series X|S 主机的《微软飞行模拟2024》将比前作占用空间小很多。 微软解释了为何新作的文件大小仅为30GB&#xff0c;约为前作的五分之一。简单来说&#xff0c;微软使用了云流媒体传输技术。公司还…

SEC重拳打击币安

美国SEC于上周四提交针对币安的拟议修订投诉&#xff0c;重点关注交易所的代币上市流程。 1.美国证券交易委员会对币安提出拟议的修订申诉。 2.SEC在驳回币安最初诉讼的动议中基本获胜&#xff0c;但在驳回动议的命令中&#xff0c;关于某些代币的若干问题仍未得到解答。 3.SEC…

木马加载器通用套路

木马加载器通用套路 加载器 木马有两种类型&#xff0c;第一种是自己写的木马&#xff0c;作为远控客户端&#xff0c;第二种是加载器 加载器就是把C2的shellcode加载到目标机器的过程。目前攻防场景下&#xff0c;主流手段是通过加载器的方式实现远控 既然是加载器&#xff…

C#开源的一个能利用Windows通知栏背单词的软件

前言 今天给大家推荐一个C#开源且免费的能利用Windows通知栏背单词的软件&#xff0c;可以让你在上班、上课等恶劣环境下安全隐蔽地背单词&#xff08;利用摸鱼时间背单词的软件&#xff09;&#xff1a;ToastFish。 操作系统要求 目前该软件只支持Windows10及以上系统&…

基于uniapp的民宿酒店预订系统(后台+小程序)

&#x1f497;博主介绍&#x1f497;&#xff1a;✌在职Java研发工程师、专注于程序设计、源码分享、技术交流、专注于Java技术领域和毕业设计✌ 温馨提示&#xff1a;文末有 CSDN 平台官方提供的老师 Wechat / QQ 名片 :) Java精品实战案例《700套》 2025最新毕业设计选题推荐…

Maven Helper 插件

推荐指数&#xff1a;★★★★★ 分析依赖冲突插件 Maven Helper插件就可免去命令行困扰。通过界面解决依赖冲突。 点击此按钮&#xff0c;切换到此工具栏 可进行相应操作&#xff1a; Conflicts&#xff08;查看冲突&#xff09;All Dependencies as List&#xff08;列表形…

vue项目中——如何用echarts实现动态航线图

在Web开发中&#xff0c;数据可视化越来越受到重视。本文将带领大家了解如何在Vue项目中使用ECharts实现动态航线图&#xff0c;如下图&#xff1a;让你的数据展示更加生动有趣。 一、准备工作 1、安装ECharts 在项目根目录下&#xff0c;运行以下命令安装ECharts&#xff1a…

【CPU】CPU的物理核、逻辑核、超线程判断及L1、L2、L3缓存和缓存行说明

CPU物理核及L1、L2、L3及缓存 CPU缓存 CPU 缓存是一种用于存储临时数据以提高计算机程序性能的内存层次结构。它通常分为三个层次&#xff1a;L1&#xff08;一级&#xff09;、L2&#xff08;二级&#xff09;和L3&#xff08;三级&#xff09;缓存。缓存大小是CPU的重…

计算机毕业设计 基于Python Django的旅游景点数据分析与推荐系统 Python+Django+Vue 前后端分离 附源码 讲解 文档

&#x1f34a;作者&#xff1a;计算机编程-吉哥 &#x1f34a;简介&#xff1a;专业从事JavaWeb程序开发&#xff0c;微信小程序开发&#xff0c;定制化项目、 源码、代码讲解、文档撰写、ppt制作。做自己喜欢的事&#xff0c;生活就是快乐的。 &#x1f34a;心愿&#xff1a;点…

SpringBoot+Thymeleaf图书管理系统

一、项目介绍 > 这是一个基于SpringBootThymeleaf实现的图书管理系统。 > 包含图书管理、作者管理、分类管理、出版社管理等功能。 > 界面简洁美观&#xff0c;代码结构清晰&#xff0c;完成度比较高&#xff0c;适用于JAVA初学者作为参考项目。 二、项目演示 三…

【刷题日记】43. 字符串相乘

43. 字符串相乘 其实就是大数乘法题&#xff0c;这道题用草稿纸演练一下&#xff0c;其实很好找到方法&#xff0c;模拟大数乘法即可。需要注意的是进位和迭代值&#xff0c;还有注意向下取整和去除前导0&#xff08;容易遗漏&#xff09;。去除前导0的时候还要注意如果全是0&…

OpenAI或于9月24日发布ChatGPT高级语音模式

&#x1f989; AI新闻 &#x1f680; OpenAI或于9月24日发布ChatGPT高级语音模式 摘要&#xff1a;科技媒体报道&#xff0c;OpenAI计划在9月24日进一步推广ChatGPT的高级语音模式&#xff0c;预计将正式发布。该模式于7月向部分ChatGPT Plus用户开放&#xff0c;提供更为真实…

Java面试篇基础部分-Java语言中的锁有哪些?

Java中的锁主要是用于保障并发线程场景下的数据一致性问题。在多线程编程中为了保证数据一致性&#xff0c;通常需要在使用对象或者方法之前进行加锁操作。也就是说要保证在同一时间内只能由一个线程来对对象进行修改&#xff0c;从而保证了数据一致性&#xff0c;保证了数据安…

阿里开源多模态大模型Ovis1.6,重塑出海电商AI格局

阿里开源Ovis1.6&#xff1a;多模态领域再夺第一 阿里再一次证明了自己在多模态领域的实力。这一次&#xff0c;阿里国际AI团队开源的多模态大模型Ovis1.6&#xff0c;不仅成功开源&#xff0c;还在多模态评测基准OpenCompass上击败了Qwen2VL-7B、InternVL2-26B和MiniCPM-V-2.…

ChatGPT 4o 使用指南 (9月更新)

首先基础知识还是要介绍得~ 一、模型知识&#xff1a; GPT-4o&#xff1a;最新的版本模型&#xff0c;支持视觉等多模态&#xff0c;OpenAI 文档中已经更新了 GPT-4o 的介绍&#xff1a;128k 上下文&#xff0c;训练截止 2023 年 10 月&#xff08;作为对比&#xff0c;GPT-4…

数据结构强化(直播课)

应用题真题分析&备考指南 (三)线性表的应用 (六)栈、队列和数组的应用 &#xff08;四&#xff09;树与二叉树的应用 1.哈夫曼&#xff08;Huffman&#xff09;树和哈夫曼编码 2.并查集及其应用&#xff08;重要&#xff09; &#xff08;四&#xff09;图的基本应用 …

伊犁职业技术学院linux 部署教学用首先创建两台linux 主机

1 一台是主机 一台是克隆 能够正常通信&#xff0c;虚拟机全局采用nat 模式 2 主机 地址 192.168.200.10 备机 192.168.200.20 、打开终端 在我们的root 用户上进行配置 另外一台机子也是如此配置流程一样&#xff0c;主要是地址改为 192.168.200.20 不再重复 最终…

【CustomPainter】绘制圆环

说明 绘制一个圆环&#xff0c;进度为0时&#xff0c;显示“圆形”。 效果 源码 MyRingPainter class MyRingPainter extends CustomPainter {final double progress;MyRingPainter({required this.progress});overridevoid paint(Canvas canvas, Size size) {double _stro…

JavaWeb纯小白笔记02:Tomcat的使用:发布项目的三种方式、配置虚拟主机、配置用户名和密码

通过Tomcat进行发布项目的目的是为了提供项目的访问能力&#xff1a;Tomcat作为Web服务器&#xff0c;能够处理HTTP请求和响应&#xff0c;将项目的内容提供给用户进行访问和使用。 一.Tomcat发布项目的三种方式&#xff1a; 第一种&#xff1a;直接在Tomcat文件夹里的webapp…