小米Root难题破解:从BL锁到模块管理的进阶之路

核心内容摘要

ChatGLM-6B GPU利用率提升实践:CUDA 12.4下显存占用与吞吐量实测分析
5步搞定Qwen3-0.6B部署,快速体验大模型推理能力

LiuJuan20260223Zimage优化升级:从512到1024分辨率,高清国风图这样生成

前言在分布式系统和微服务架构日益普及的今天负载均衡已经成为保障系统高可用、高性能的

关键技术。

然而在实际架构设计中开发团队经常面临一个重要的选择客户端负载均衡还是服务端负载均衡这两种方案各有千秋选对了能够事半功倍选错了则可能带来性能瓶颈或运维噩梦。

本文将从概念原理、技术对比、实现方式、选型建议等多个维度对两种负载均衡方案进行全面分析为你的架构决策提供参考。

概念解析

1 服务端负载均衡定义服务端负载均衡是指负载均衡器部署在服务提供者和服务消费者之间由专门的负载均衡设备或软件来接收客户端请求并根据预设的算法将请求分发到后端的服务实例上。

工作原理客户端 → 负载均衡器 → 服务实例A ↘ → 服务实例B → 服务实例C客户端只知道负载均衡器的地址并不知道后端实际有多少个服务实例。

所有的请求都会先到达负载均衡器由它决定将请求转发给哪个服务实例。

核心特点客户端感知简单只需配置负载均衡器地址负载均衡逻辑集中在服务端便于统一管理客户端无感知服务实例的上下线对客户端透明

2 客户端负载均衡定义客户端负载均衡是指负载均衡逻辑集成在客户端应用中客户端从服务注册中心获取服务实例列表并根据负载均衡算法自主选择要调用的服务实例。

工作原理服务注册中心Eureka/Nacos ↑ | 获取服务列表 客户端A → 服务实例A | → 服务实例B | → 服务实例C客户端需要集成负载均衡组件运行时动态获取服务实例列表并基于算法选择目标实例直接发起调用。

核心特点客户端需要具备负载均衡能力客户端直接与目标服务实例通信减少了一跳网络开销需要服务注册/发现机制的支持

3 核心差异维度服务端负载均衡客户端负载均衡负载均衡位置服务端独立设备/组件客户端应用内部请求路径客户端 → LB → 服务实例客户端 → 服务实例直连服务发现无需必须依赖服务注册中心客户端复杂度简单较高需集成LB组件网络开销多一跳直连开销更小控制粒度统一控制便于管理分散到各个客户端

技术对比

1 部署位置服务端负载均衡通常部署在网络边界如数据中心入口、DMZ区作为独立的硬件设备F

A10或软件服务Nginx、HAProxy需要专门的运维团队进行维护和监控客户端负载均衡集成在每个客户端应用进程中作为客户端应用的一个组件或库存在随客户端应用一起部署和升级

2 性能影响服务端负载均衡优势可以将复杂的负载均衡算法和健康检查逻辑集中处理不占用客户端资源劣势增加了一跳网络延迟在高并发场景下可能成为性能瓶颈带宽消耗所有请求流量都经过负载均衡器对网络带宽要求较高客户端负载均衡优势客户端直连服务实例减少一跳网络延迟提升响应速度劣势客户端需要消耗CPU和内存资源进行负载计算和服务列表缓存带宽消耗请求流量直接分发到各服务实例无需集中转发

3 适用场景服务端负载均衡适用于传统单体应用架构需要对流量进行统一管控的场景服务实例对外暴露的场景如API网关需要SSL卸载、WAF等安全功能的场景客户端能力受限或无法集成复杂逻辑的场景如移动端、IoT设备客户端负载均衡适用于微服务架构特别是基于Spring Cloud、Dubbo等框架的体系服务间调用频繁的场景需要精细控制服务调用策略的场景客户端有能力集成复杂组件的场景

4 容错能力服务端负载均衡主动健康检查可以定期对后端服务实例进行健康检查自动剔除不健康实例熔断降级支持在服务异常时进行熔断避免雪崩效应会话保持支持基于会话的粘性路由优势集中管理容错策略统一实施客户端负载均衡重试机制可以在客户端层面实现请求重试提升调用成功率超时控制每个客户端可以独立配置超时策略服务熔断结合Hystrix、Sentinel等组件实现熔断劣势容错逻辑分散在各个客户端容易出现配置不一致的问题

5 实现复杂度服务端负载均衡配置复杂度中等需要配置负载均衡规则、健康检查等开发复杂度低客户端无需任何特殊配置运维复杂度高需要专门的负载均衡器运维团队客户端负载均衡配置复杂度较高需要配置注册中心、负载均衡策略等开发复杂度中等需要集成相应的SDK或框架运维复杂度中等主要是服务注册中心的维护

6 扩展性对比架构图对比文字描述服务端负载均衡架构┌─────────────────┐ │ 互联网/外部 │ └────────┬────────┘ │ ┌────────▼────────┐ │ 负载均衡器(LB) │ ← 统一流量入口 │ (Nginx/F

│ 可集中管控 └────────┬────────┘ │ ┌───────────────────┼───────────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ 服务A-1 │ │ 服务A-2 │ │ 服务A-3 │ └─────────┘ └─────────┘ └─────────┘客户端负载均衡架构┌─────────────────┐ │ 服务注册中心 │ ← 服务中心 │ (Eureka/Nacos) │ 维护实例列表 └────────┬────────┘ │ ┌───────────────────┼───────────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ 客户端A │ │ 客户端B │ │ 客户端C │ │ (内置LB) │ │ (内置LB) │ │ (内置LB) │ └────┬────┘ └────┬────┘ └────┬────┘ │ │ │ └───────────────────┼───────────────────┘ │ ┌───────────────────┼───────────────────┐ │ │ │ ┌────▼────┐ ┌────▼────┐ ┌────▼────┐ │ 服务A-1 │ │ 服务A-2 │ │ 服务A-3 │ └─────────┘ └─────────┘ └─────────┘

实现方式

1 客户端负载均衡实现

3.

1 Spring Cloud LoadBalancer概述Spring Cloud LoadBalancer是Spring Cloud官方推出的客户端负载均衡器用于替代已进入维护模式的Netflix Ribbon。

特点基于Spring Reactor响应式编程模型与Spring Cloud生态无缝集成支持多种负载均衡策略轮询、随机、权重等支持自定义负载均衡规则核心代码示例//

添加依赖dependencygroupIdorg.springframework.cloud/groupIdartifactIdspring-cloud-starter-loadbalancer/artifactId/dependency//

配置类ConfigurationpublicclassLoadBalancerConfig{BeanReactorLoadBalancerServiceInstancerandomLoadBalancer(Environmentenvironment,LoadBalancerClientFactoryloadBalancerClientFactory){Stringnameenvironment.getProperty(LoadBalancerClientFactory.PROPERTY_NAME);returnnewRandomLoadBalancer(loadBalancerClientFactory.getLazyProvider(name,ServiceInstanceListSupplier.class),name);}}//

使用方式ServicepublicclassOrderService{AutowiredprivateRestTemplaterestTemplate;LoadBalanced// 关键注解启用客户端负载均衡publicvoidcallProductService(){StringresponserestTemplate.getForObject(http://product-service/products,// 服务名而非具体IPString.class);}}使用场景基于Spring Cloud的微服务架构需要与Spring Cloud Gateway、OpenFeign等组件配合使用对响应式编程有需求的场景

3.

2 Dubbo负载均衡概述Dubbo作为阿里巴巴开源的高性能RPC框架内置了多种客户端负载均衡策略。

支持的负载均衡策略Random随机选择按权重设置随机概率RoundRobin轮询按公约后的权重设置轮询比率LeastActive最少活跃调用数相同活跃数的随机ConsistentHash一致性Hash相同参数的请求总是发往同一提供者ShortestResponse最短响应时间选择响应时间最短的提供者核心配置示例!-- 服务消费者配置 --dubbo:referenceiduserServiceinterfacecom.example.UserServiceloadbalancerandomcheckfalse/!-- 或者使用注解方式 --Reference(loadbalance leastactive, timeout

private UserService userService;!-- 自定义负载均衡策略 --public class CustomLoadBalance extends AbstractLoadBalance { Override protectedTInvokerTdoSelect(ListInvokerT invokers, URL url, Invocation invocation) { // 自定义选择逻辑 return invokers.get(

; } }使用场景基于Dubbo框架的RPC调用需要精细控制服务调用策略的场景对性能有极高要求的内部服务调用

3.

3 Nacos负载均衡概述NacosNaming and Configuration Service是阿里巴巴开源的服务发现与配置管理平台不仅提供服务注册发现功能还内置了轻量级的客户端负载均衡能力是国内微服务架构中使用最广泛的技术栈之一。

Nacos负载均衡的工作机制Nacos的负载均衡能力主要通过两种方式体现服务发现 客户端选择Nacos作为服务注册中心客户端获取服务实例列表后可以选择使用Nacos SDK自带的负载均衡算法或结合Ribbon/Spring Cloud LoadBalancer等组件进行负载均衡。

Nacos SDK内置负载均衡Nacos客户端SDK提供了多种负载均衡策略供直接调用。

支持的负载均衡策略Nacos支持以下负载均衡策略通过nacos.naming.loadbalance.strategy配置策略名称说明适用场景random随机选择服务实例通用场景简单高效weight基于权重的随机选择服务实例配置不同需要按权重分配流量round_robin轮询选择需要保证请求均匀分配的场景consistent_hash一致性Hash需要保持会话粘性或缓存亲和性的场景核心配置示例// 方式一使用Nacos原生SDK 自定义负载均衡策略importcom.alibaba.nacos.api.NacosFactory;importcom.alibaba.nacos.api.naming.NamingService;importcom.alibaba.nacos.api.naming.pojo.Instance;publicclassNacosLoadBalanceExample{publicstaticvoidmain(String[]args)throwsException{// 创建Nacos命名服务NamingServicenamingServiceNacosFactory.createNamingService(

127.

0.

1:

;// 获取健康的服务实例列表ListInstanceinstancesnamingService.getAllInstances(user-service,true);// 使用Nacos提供的负载均衡工具类InstanceselectedInstancecom.alibaba.nacos.client.naming.utils.Chooser.random(instances);// 或使用权重选择InstanceweightedInstancecom.alibaba.nacos.client.naming.utils.Chooser.weightedRandom(instances);System.out.println(Selected instance: selectedInstance.getIp():selectedInstance.getPort());}}Spring Cloud Alibaba集成配置# application.yml配置spring:cloud:nacos:discovery:server-addr:

127.

0.

1:8848namespace:devgroup:DEFAULT_GROUP# 负载均衡策略配置如果使用Nacos Ribbonloadbalance:strategy:random# 可选: random, weight, round_robin// Spring Cloud Alibaba OpenFeign使用示例FeignClient(nameuser-service,configurationFeignConfig.class)publicinterfaceUserServiceClient{GetMapping(/users/{id})UsergetUserById(PathVariable(id)Longid);}// 启用Nacos服务发现SpringBootApplicationEnableDiscoveryClientEnableFeignClientspublicclassApplication{publicstaticvoidmain(String[]args){SpringApplication.run(Application.class,args);}}动态权重调整示例Nacos支持动态调整服务实例权重权重越高被选中的概率越大// 动态设置实例权重ServicepublicclassDynamicWeightService{AutowiredprivateNamingServicenamingService;publicvoidupdateInstanceWeight(StringserviceName,Stringip,intport,floatweight){try{// 获取当前实例InstanceinstancenamingService.selectOneHealthyInstance(serviceName,ip,port);// 动态设置权重范围

0 -

0instance.setWeight(weight);// 注册更新后的实例namingService.registerInstance(serviceName,instance);}catch(Exceptione){e.printStackTrace();}}}Nacos负载均衡的优势服务发现与负载均衡一体化无需引入额外的负载均衡组件简化架构动态服务感知服务实例上下线实时感知自动调整负载均衡策略多环境支持支持namespace、group等多维度隔离权重动态调整支持运行时动态调整实例权重实现灰度发布和流量倾斜健康检查内置健康检查机制自动剔除不健康实例国内生态友好与Spring Cloud Alibaba生态深度集成文档和社区支持完善与其他组件的集成集成方式说明Nacos Ribbon使用Nacos作为服务发现中心Ribbon负责负载均衡算法Nacos Spring Cloud LoadBalancerSpring Cloud 2020后的推荐组合响应式编程模型Nacos SDK内置LB直接使用Nacos SDK提供的负载均衡能力无需额外组件Nacos DubboDubbo使用Nacos作为注册中心Dubbo内置负载均衡策略使用场景基于Spring Cloud Alibaba的微服务架构需要服务发现与配置管理一体化的场景国内企业项目社区支持和生态完善需要动态权重调整实现灰度发布的场景多租户、多环境部署需要隔离的场景实际应用案例某电商平台在双十一大促期间使用Nacos作为服务注册中心结合动态权重调整功能优先将流量分配给高性能服务器权重设置为

8普通服务器权重设置为

2作为补充根据实时监控数据动态调整各实例权重新版本发布时通过权重控制实现平滑灰度从5%流量逐步提升到100%

3.

4 gRPC客户端负载均衡概述gRPC支持客户端负载均衡通过NameResolver和LoadBalancer接口实现。

实现方式// 使用gRPC Java客户端ManagedChannelchannelManagedChannelBuilder.forTarget(dns:///my-service.example.com:

.defaultLoadBalancingPolicy(round_robin)// 轮询策略.build();// 支持的负载均衡策略// - round_robin: 轮询// - pick_first: 选择第一个// - grpclb: gRPC负载均衡服务// - 自定义策略使用场景基于gRPC的微服务通信多语言环境下的服务调用需要流式调用的场景

2 服务端负载均衡实现

3.

1 Nginx概述Nginx是一款高性能的HTTP和反向代理服务器广泛应用于服务端负载均衡场景。

特点高性能、低内存占用支持多种负载均衡算法支持健康检查支持SSL卸载、缓存、压缩等功能核心配置示例upstream backend_servers { # 轮询策略默认 server

192.

168.

10:8080 weight1; server

192.

168.

11:8080 weight2; # 权重更高 server

192.

168.

12:8080 backup; # 备用服务器 # 最少连接数策略 # least_conn; # IP Hash策略 # ip_hash; # 健康检查 check interval3000 rise2 fall3 timeout1000; } server { listen 80; server_name example.com; location / { proxy_pass http://backend_servers; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; # 超时配置 proxy_connect_timeout 60s; proxy_read_timeout 60s; } # SSL配置示例 # server { # listen 443 ssl; # ssl_certificate /path/to/cert.pem; # ssl_certificate_key /path/to/key.pem; # } }负载均衡算法轮询Round Robin按时间顺序逐一分配权重轮询Weighted Round Robin根据权重分配权重越高分配越多最少连接Least Connections优先分配给连接数最少的服务器IP Hash基于客户端IP的hash值分配保证会话粘性URL Hash基于请求URL的hash值分配使用场景Web应用入口负载均衡API网关静态资源服务需要SSL卸载的场景

3.

2 HAProxy概述HAProxy是一款免费、开源、高性能的负载均衡软件特别适合高并发场景。

特点单进程事件驱动模型性能卓越支持四层TCP和七层HTTP负载均衡强大的健康检查机制丰富的监控统计功能支持会话保持核心配置示例# 全局配置 global log /dev/log local0 log /dev/log local1 notice maxconn 4096 user haproxy group haproxy # 默认配置 defaults log global mode http option httplog option dontlognull retries 3 timeout connect 5000 timeout client 50000 timeout server 50000 # 前端配置 frontend www-in bind *:80 default_backend www-backend # 后端配置 backend www-backend balance roundrobin # 轮询策略 # balance leastconn # 最少连接 # balance source # 源地址hash server web1

192.

168.

10:8080 check inter 2000 rise 2 fall 3 server web2

192.

168.

11:8080 check inter 2000 rise 2 fall 3 server web3

192.

168.

12:8080 check inter 2000 rise 2 fall 3 backup # 健康检查配置 option httpchk GET /health http-check expect status 200 # 统计页面配置 listen stats bind *:8080 stats enable stats uri /stats stats refresh 10s stats admin if TRUE使用场景高并发Web应用需要四层负载均衡的场景如数据库代理对性能要求极高的场景需要详细监控统计的场景

3.

3 F5 BIG-IP概述F5 BIG-IP是企业级硬件负载均衡器提供全面的流量管理解决方案。

特点硬件加速性能强劲全面的应用交付功能强大的安全防护WAF、DDoS防护丰富的应用层优化能力完善的监控和管理界面核心功能功能模块说明LTM (Local Traffic Manager)本地流量管理支持多种负载均衡算法ASM (Application Security Manager)应用安全管理提供WAF功能APM (Access Policy Manager)访问策略管理支持SSO、认证等DNS (GTM)全局服务器负载均衡支持多数据中心AFM (Advanced Firewall Manager)高级防火墙管理配置示例iRules脚本# 基于URL路径的负载均衡 when HTTP_REQUEST { switch [HTTP::path] { /api/ { pool api_pool } /static/ { pool static_pool } default { pool web_pool } } } # 基于HTTP头的路由 when HTTP_REQUEST { if { [HTTP::header X-Environment] equals production } { pool production_pool } else { pool staging_pool } }使用场景大型企业级应用金融、电商等对安全和可靠性要求极高的场景多数据中心流量调度需要全面应用交付功能的场景

选型建议

1 不同业务场景的选型策略场景一微服务架构中的服务间调用推荐方案客户端负载均衡理由微服务间调用频繁客户端直连可以减少网络延迟结合服务注册中心可以实现动态服务发现每个服务可以独立配置负载均衡策略灵活性高技术选型// Spring Cloud生态Spring Cloud LoadBalancer// Dubbo生态Dubbo内置负载均衡// gRPC生态gRPC客户端负载均衡案例某电商平台的订单服务和库存服务之间采用Dubbo进行RPC调用配置leastactive策略将请求优先分配给负载较低的服务实例提升整体吞吐量。

场景二对外暴露的API入口推荐方案服务端负载均衡理由需要统一的安全策略SSL卸载、WAF防护客户端多样Web、移动端、第三方调用客户端负载均衡难以统一管理可以在边界进行统一的流量管控和限流技术选型# 基础版Nginx / HAProxy# 进阶版Kubernetes Ingress Nginx# 企业版F5 BIG-IP / 云负载均衡AWS ELB、阿里云SLB案例某金融App的后端API入口使用Nginx作为负载均衡器配置SSL证书卸载并结合Lua脚本实现基于用户ID的灰度发布策略。

场景三传统单体应用集群化部署推荐方案服务端负载均衡理由应用本身不具备服务发现能力部署架构简单无需引入复杂的注册中心运维团队已有成熟的Nginx/HAProxy运维经验技术选型# Nginx配置示例 upstream app_cluster { least_conn; server

10.

0.

10:8080; server

10.

0.

11:8080; server

10.

0.

12:8080; }案例某企业的OA系统采用传统的WAR包部署方式通过Nginx实现3个Tomcat实例的负载均衡既保证了高可用又无需对应用代码进行改造。

场景四高并发实时交易系统推荐方案混合架构理由入口层使用服务端负载均衡Nginx/F5进行流量分发和安全防护内部服务间采用客户端负载均衡减少延迟结合两种方案的优点兼顾性能和可管理性架构示例客户端 ↓ F5负载均衡SSL卸载、WAF防护 ↓ Nginx集群应用层路由 ↓ 微服务A客户端负载均衡 → 微服务B客户端负载均衡案例某证券交易系统采用F5作为入口负载均衡内部微服务使用Spring Cloud LoadBalancer进行服务间调用在高并发压力下仍能保持毫秒级响应。

2 选型决策树是否需要对外暴露服务 ├─ 是 → 服务端负载均衡 │ ├─ 是否有硬件预算 │ │ ├─ 是 → F5 / A10等硬件负载均衡器 │ │ └─ 否 → Nginx / HAProxy / 云负载均衡 │ └─ 是否需要高级安全功能 │ ├─ 是 → F5 ASM / 云WAF │ └─ 否 → Nginx ModSecurity │ └─ 否内部服务调用 → 客户端负载均衡 ├─ 使用的技术栈 │ ├─ Spring Cloud → Spring Cloud LoadBalancer │ ├─ Dubbo → Dubbo内置负载均衡 │ ├─ gRPC → gRPC客户端负载均衡 │ └─ 其他 → 自定义或第三方客户端LB └─ 是否需要统一流量管控 ├─ 是 → 引入服务网格Istio/Linkerd └─ 否 → 纯客户端负载均衡

3 常见组合模式组合一Nginx Spring Cloud LoadBalancerNginx作为API网关处理外部流量微服务间使用Spring Cloud LoadBalancer进行调用适合基于Spring Cloud的微服务架构组合二F5 DubboF5作为入口提供安全防护和全局负载均衡内部Dubbo服务使用客户端负载均衡适合金融、电信等高性能场景组合三云负载均衡 客户端LB使用云厂商提供的负载均衡服务如AWS ALB结合服务注册中心实现自动扩缩容适合云原生应用

五、

总结展望

1 优缺点

总结服务端负载均衡优点缺点✅ 客户端实现简单无感知❌ 增加网络延迟多一跳✅ 集中管理易于统一配置❌ 负载均衡器可能成为单点瓶颈✅ 支持丰富的附加功能SSL、缓存、压缩❌ 所有流量集中带宽压力大✅ 运维成熟监控体系完善❌ 扩展性受限于负载均衡器性能✅ 不依赖服务注册中心❌ 灵活性相对较低客户端负载均衡优点缺点✅ 直连服务实例网络延迟低❌ 客户端实现复杂度增加✅ 分布式架构无中心化瓶颈❌ 需要服务注册/发现机制支持✅ 每个客户端可独立配置策略❌ 配置分散管理难度大✅ 天然支持动态扩缩容❌ 客户端资源消耗增加✅ 灵活性高易于定制❌ 需要客户端配合升级

2 负载均衡技术发展趋势

5.

1 服务网格的兴起随着云原生技术的普及服务网格Service Mesh正在成为微服务架构的标配。

Istio、Linkerd等服务网格将负载均衡功能下沉到基础设施层实现了业务逻辑与流量管理的彻底解耦。

优势对应用代码零侵入统一的流量管理、监控、安全策略支持复杂的灰度发布、蓝绿部署策略示例架构应用Pod ↓ Sidecar代理Envoy← 服务网格数据平面 ↓ 服务网格控制平面Istio← 统一配置和管理

5.

2 智能负载均衡传统的负载均衡算法轮询、随机等逐渐无法满足复杂场景的需求基于机器学习的智能负载均衡开始崭露头角。

技术方向基于实时性能指标的动态调整预测性负载分配提前规避热点多维度因素综合决策延迟、错误率、负载等示例传统策略轮询分配 智能策略根据服务实例的CPU使用率、响应时间、错误率等 多个维度进行综合评分动态调整分配权重

5.

3 云原生负载均衡各大云厂商提供的云原生负载均衡服务如AWS ALB/NLB、Google Cloud Load Balancing正在成为主流选择。

优势完全托管无需运维自动弹性伸缩与云生态深度集成全球负载均衡能力

5.

4 边缘计算负载均衡随着边缘计算的发展负载均衡技术正向边缘节点延伸实现就近接入和边缘智能调度。

应用场景CDN边缘节点的智能调度IoT设备的就近接入低时延应用如云游戏、AR/VR

3 给开发者的建议不要过度设计对于简单的应用Nginx服务端负载均衡往往足够不要盲目引入复杂的客户端负载均衡。

关注可观测性无论选择哪种方案都要建立完善的监控体系实时了解流量分布和服务健康状态。

考虑演进路径在选择方案时要考虑未来业务发展的需求预留演进空间。

混合使用是常态在实际架构中服务端和客户端负载均衡往往配合使用不要非此即彼。

拥抱云原生如果使用云服务优先考虑云厂商提供的负载均衡服务减少运维负担。

结语客户端负载均衡和服务端负载均衡各有其适用场景没有绝对的好坏之分。

在实际架构设计中需要根据业务特点、团队能力、技术栈等因素进行综合考量。

随着云原生技术的发展负载均衡的边界正在变得模糊服务网格等新技术正在重塑负载均衡的形态。

作为开发者我们需要不断学习与时俱进才能在架构设计中做出最优的选择。

9.1comapp动漫官方版-9.1comapp动漫官方版应用

百度百家号客服电话人工服务

123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123 123