• un8.1:在nacos微服务已经被注册user-center和content-center


            随着SpringBoot框架的发展,更多的人意识到SpringCloud带给大家的便利性,其实说白了,SpringCloud就是将多个SpringBoot整合到一起,当然,我们也叫集成。

    那么SpringBootSpringCloud有什么区别呢?

    SpringBoot专注于快速方便的开发单个个体微服务

            SpringCloud是关注全局的微服务协调整理治理框架,它将Spring Boot开发的一个个单体微服务整   合并管理起来,为各个微服务之间提供,配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策 竞选、分布式会话等等集成服务。

            SpringBoot可以离开SpringCloud独立使用开发项目, 但是SpringCloud离不开SpringBoot ,属于依赖的关系.

            SpringBoot专注于快速、方便的开发单个微服务个体,SpringCloud关注全局的服务治理框架。

    关于SpringCloud的介绍可以参考如下链接。

    Home · alibaba/spring-cloud-alibaba Wiki · GitHub

    接下里,我就和大家分享一下,如何将springboot集成spring cloud并在nacos中成功注册。

    一、集成SpringCloudAlibaba,在pom.xml中添加依赖。

    1. <dependencyManagement>
    2. <dependencies>
    3. <dependency>
    4. <groupId>org.springframework.cloudgroupId>
    5. <artifactId>spring-cloud-dependenciesartifactId>
    6. <version>Greenwich.SR1version>
    7. <type>pomtype>
    8. <scope>importscope>
    9. dependency>
    10. <dependency>
    11. <groupId>org.springframework.cloudgroupId>
    12. <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    13. <version>0.9.0.RELEASEversion>
    14. <type>pomtype>
    15. <scope>importscope>
    16. dependency>
    17. dependencies>
    18. dependencyManagement>

    二、服务发现Nacos+Ribbon实现负载均衡。

    1、SpringCloudAlibaba微服务全景架构。

    2、 负载均衡的意义是什么?

            在计算中,负载均衡可以改善跨计算机,计算机集群,网络链接,中央处理单元或磁盘驱动器等多种计算资源工作的负载分布。

            负载平衡旨在优化资源的使用,最大化吞吐量、最小化响应时间、避免任何单一资源的过载。

    3、Nacos介绍及下载安装,大家可以直接去网站下载,也可以私我。

    Nacos介绍请参考:https://nacos.io/zh-cn/docs/what-is-nacos.html

    下载:Releases · alibaba/nacos · GitHub

    安装方法:Nacos 快速开始

    4、运行nacos。

    切换到bin目录,在命令窗口输入命令:startup.cmd -m standalone(如果十在虚拟机,那么命令为:sh startup.sh -m standalone)

     5、成功启动后打开网址查看,网址:http://localhost:8848/nacos/index.html

    6、输入用户命和密码,都是nacos,点击登录,登录成功后显示如下页面,之后会在服务列表进行查看。

     7、建立两个项目,一个是user,一个是concent,为了使教程更加简单易懂,我们将微服务缩减到2个,分别是用户中心(user-center)和内容中心(content-center),content-center(内容中心微服务)需要向user-center(用户中心微服务)发送请求获取用户的微信昵称,也就是说user-center是消息提供者,content-center是消息消费者,业务非常简单清晰。

    8、user-center(用户中心微服务)和content-center(内容中心微服务)通过Ribbon向NacosServer(服务发现组件)注册服务,由NacosServer进行管理。

    三、使用Ribbon实现负载均衡。
          在使用之前,我们需要知道Ribbon是什么?
          Spring Cloud Ribbon是一个基于HTTP和TCP的客户端负载均衡工具,它基于Netflix Ribbon实现。通过Spring Cloud的封装,可以让我们轻松地将Http请求(Feign)自动转换成客户端负载均衡的服务调用。微服务间的调用,API网关的请求转发等内容,实际上都是通过Ribbon来实现的,也就是说, Spring Cloud Ribbon是基于Ribbon实现的工具。
    1、架构演进。

    2、使用Ribbon将user-center微服务注册到Nacos。

    在pom.xml中添加依赖。

    1. <dependency>
    2. <groupId>org.springframework.cloudgroupId>
    3. <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    4. dependency>

    在application.yml中添加配置。

    1. spring:
    2. cloud:
    3. nacos:
    4. discovery:
    5. #指定nacos server的地址,用于微服务发现
    6. server-addr: localhost:8848
    7. #设置机房名称(指定集群名称)
    8. cluster-name: BeiJing
    9. #在nacos中配置命名空间(指定namespace),并且获得uuid
    10. #namespace: 980af6bb-ce43-43f2-91de-9878ca25fa3e
    11. #cluster-name: NanJing
    12. #指定实例元数据
    13. #metadata:
    14. # instance: I'm instance meta data
    15. application:
    16. name: user-center

    配置权重规则

    一个服务可以有多个实例,例如我们的 user-service,可以有:

        127.0.0.1:8081
        127.0.0.1:8082
        127.0.0.1:8083

    假如这些实例分布于全国各地的不同机房,例如:

        127.0.0.1:8081,在杭州机房
        127.0.0.1:8082,在杭州机房
        127.0.0.1:8083,在上海机房

    Nacos就将同一机房内的实例,划分为一个集群。

    微服务互相访问时,应该尽可能访问同集群实例,因为本地访问速度更快。当本集群内不可用时,才访问其它集群例如:杭州机房内的 order-service 应该优先访问同机房的 user-service。

    ​ 

     将规则设置为同集群优先。

    在user_center下创建一个configuration包。

     然后创建一个NacosSameClusterWeightedRule类,它自带的两个类,内容如下。

    NacosSameClusterWeightedRule

    1. package com.example.user_center.configuration;
    2. import com.alibaba.nacos.api.exception.NacosException;
    3. import com.alibaba.nacos.api.naming.NamingService;
    4. import com.alibaba.nacos.api.naming.pojo.Instance;
    5. import com.alibaba.nacos.client.naming.core.Balancer;
    6. import com.netflix.client.config.IClientConfig;
    7. import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    8. import com.netflix.loadbalancer.BaseLoadBalancer;
    9. import com.netflix.loadbalancer.Server;
    10. import lombok.extern.slf4j.Slf4j;
    11. import org.springframework.beans.factory.annotation.Autowired;
    12. import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
    13. import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
    14. import org.springframework.util.CollectionUtils;
    15. import java.util.ArrayList;
    16. import java.util.List;
    17. import java.util.Objects;
    18. import java.util.stream.Collectors;
    19. @Slf4j
    20. public class NacosSameClusterWeightedRule extends AbstractLoadBalancerRule {
    21. @Autowired
    22. private NacosDiscoveryProperties nacosDiscoveryProperties;
    23. @Override
    24. public void initWithNiwsConfig(IClientConfig iClientConfig) {
    25. }
    26. @Override
    27. public Server choose(Object o) {
    28. try {
    29. //拿到配置文件中的集群名称BeiJing
    30. String clusterName = nacosDiscoveryProperties.getClusterName();
    31. BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
    32. //想要请求的微服务的名称
    33. String name = loadBalancer.getName();
    34. //获取服务发现的相关API
    35. NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
    36. //1、找到指定服务的所有实例A
    37. List instances = namingService.selectInstances(name, true);
    38. //2、过滤出相同集群下的所有实例B
    39. List sameClusterInstances = instances.stream().filter(instance -> Objects.equals(instance.getClusterName(), clusterName)).collect(Collectors.toList());
    40. //3、如果B是空,就用A
    41. List instancesToBeChoosen = new ArrayList();
    42. if(CollectionUtils.isEmpty(sameClusterInstances)){
    43. instancesToBeChoosen = instances;
    44. log.warn("发生跨集群的调用,name={}, clusterName={}, instances={}", name, clusterName, instances);
    45. } else {
    46. instancesToBeChoosen = sameClusterInstances;
    47. }
    48. //4、基于权重的负载均衡算法,返回一个实例
    49. Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToBeChoosen);
    50. log.info("选择的实例是:port={}, instance={}", instance.getPort(), instance);
    51. return new NacosServer(instance);
    52. } catch (NacosException e) {
    53. log.error("发生异常了", e);
    54. return null;
    55. }
    56. }
    57. }
    58. class ExtendBalancer extends Balancer {
    59. public static Instance getHostByRandomWeight2(List hosts){
    60. return getHostByRandomWeight(hosts);
    61. }
    62. }

    ExtendBalancer

    1. package com.example.user_center.configuration;
    2. import com.alibaba.nacos.api.exception.NacosException;
    3. import com.alibaba.nacos.api.naming.NamingService;
    4. import com.alibaba.nacos.api.naming.pojo.Instance;
    5. import com.alibaba.nacos.client.naming.core.Balancer;
    6. import com.netflix.client.config.IClientConfig;
    7. import com.netflix.loadbalancer.AbstractLoadBalancerRule;
    8. import com.netflix.loadbalancer.BaseLoadBalancer;
    9. import com.netflix.loadbalancer.Server;
    10. import lombok.extern.slf4j.Slf4j;
    11. import org.springframework.beans.factory.annotation.Autowired;
    12. import org.springframework.cloud.alibaba.nacos.NacosDiscoveryProperties;
    13. import org.springframework.cloud.alibaba.nacos.ribbon.NacosServer;
    14. import org.springframework.util.CollectionUtils;
    15. import java.util.ArrayList;
    16. import java.util.List;
    17. import java.util.Objects;
    18. import java.util.stream.Collectors;
    19. @Slf4j
    20. public class NacosSameClusterWeightedRule extends AbstractLoadBalancerRule {
    21. @Autowired
    22. private NacosDiscoveryProperties nacosDiscoveryProperties;
    23. @Override
    24. public void initWithNiwsConfig(IClientConfig iClientConfig) {
    25. }
    26. @Override
    27. public Server choose(Object o) {
    28. try {
    29. //拿到配置文件中的集群名称BeiJing
    30. String clusterName = nacosDiscoveryProperties.getClusterName();
    31. BaseLoadBalancer loadBalancer = (BaseLoadBalancer) this.getLoadBalancer();
    32. //想要请求的微服务的名称
    33. String name = loadBalancer.getName();
    34. //获取服务发现的相关API
    35. NamingService namingService = nacosDiscoveryProperties.namingServiceInstance();
    36. //1、找到指定服务的所有实例A
    37. List instances = namingService.selectInstances(name, true);
    38. //2、过滤出相同集群下的所有实例B
    39. List sameClusterInstances = instances.stream().filter(instance -> Objects.equals(instance.getClusterName(), clusterName)).collect(Collectors.toList());
    40. //3、如果B是空,就用A
    41. List instancesToBeChoosen = new ArrayList();
    42. if(CollectionUtils.isEmpty(sameClusterInstances)){
    43. instancesToBeChoosen = instances;
    44. log.warn("发生跨集群的调用,name={}, clusterName={}, instances={}", name, clusterName, instances);
    45. } else {
    46. instancesToBeChoosen = sameClusterInstances;
    47. }
    48. //4、基于权重的负载均衡算法,返回一个实例
    49. Instance instance = ExtendBalancer.getHostByRandomWeight2(instancesToBeChoosen);
    50. log.info("选择的实例是:port={}, instance={}", instance.getPort(), instance);
    51. return new NacosServer(instance);
    52. } catch (NacosException e) {
    53. log.error("发生异常了", e);
    54. return null;
    55. }
    56. }
    57. }
    58. class ExtendBalancer extends Balancer {
    59. public static Instance getHostByRandomWeight2(List hosts){
    60. return getHostByRandomWeight(hosts);
    61. }
    62. }

     创建Ribbon配置类,他不能和Java同包,所以我将ribbonconfiguration创建在了Java下。

    1. package ribbonconfiguration;
    2. import com.example.user_center.configuration.NacosSameClusterWeightedRule;
    3. import com.netflix.loadbalancer.IRule;
    4. import org.springframework.context.annotation.Bean;
    5. import org.springframework.context.annotation.Configuration;
    6. @Configuration
    7. public class RibbonConfiguration {
    8. @Bean
    9. public IRule ribbonRule(){
    10. return new NacosSameClusterWeightedRule(); //同集群优先规则
    11. }
    12. }

     Ribbon全局配置

    1. package com.example.user_center.configuration;
    2. import org.springframework.cloud.netflix.ribbon.RibbonClients;
    3. import org.springframework.context.annotation.Configuration;
    4. import ribbonconfiguration.RibbonConfiguration;
    5. @Configuration
    6. //Ribbon全局配置
    7. @RibbonClients(defaultConfiguration = RibbonConfiguration.class)
    8. public class UserCenterRibbonConfiguration {
    9. }

    做完此步骤后,在另一个项目中也做如此配置,yml文件需要改端口号和名字,然后将两个项目进行启动。

    四、最后,点开nacos中测试。

     我们会发现,已经有了两个注册成功的springboot,如此,我们便实现了在nacos微服务注册user-center和content-center。

    最后,附上完整版pom.xml

    1. <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    2. xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    3. <modelVersion>4.0.0modelVersion>
    4. <parent>
    5. <groupId>org.springframework.bootgroupId>
    6. <artifactId>spring-boot-starter-parentartifactId>
    7. <version>2.1.5.RELEASEversion>
    8. <relativePath/>
    9. parent>
    10. <groupId>com.examplegroupId>
    11. <artifactId>user_centerartifactId>
    12. <version>0.0.1-SNAPSHOTversion>
    13. <name>user_centername>
    14. <description>user_centerdescription>
    15. <properties>
    16. <java.version>1.8java.version>
    17. properties>
    18. <dependencies>
    19. <dependency>
    20. <groupId>org.springframework.bootgroupId>
    21. <artifactId>spring-boot-starter-webartifactId>
    22. dependency>
    23. <dependency>
    24. <groupId>org.springframework.bootgroupId>
    25. <artifactId>spring-boot-starter-testartifactId>
    26. <scope>testscope>
    27. dependency>
    28. <dependency>
    29. <groupId>org.springframework.cloudgroupId>
    30. <artifactId>spring-cloud-starter-alibaba-nacos-discoveryartifactId>
    31. dependency>
    32. <dependency>
    33. <groupId>org.projectlombokgroupId>
    34. <artifactId>lombokartifactId>
    35. <version>1.18.12version>
    36. dependency>
    37. dependencies>
    38. <dependencyManagement>
    39. <dependencies>
    40. <dependency>
    41. <groupId>org.springframework.cloudgroupId>
    42. <artifactId>spring-cloud-dependenciesartifactId>
    43. <version>Greenwich.SR1version>
    44. <type>pomtype>
    45. <scope>importscope>
    46. dependency>
    47. <dependency>
    48. <groupId>org.springframework.cloudgroupId>
    49. <artifactId>spring-cloud-alibaba-dependenciesartifactId>
    50. <version>0.9.0.RELEASEversion>
    51. <type>pomtype>
    52. <scope>importscope>
    53. dependency>
    54. dependencies>
    55. dependencyManagement>
    56. <build>
    57. <plugins>
    58. <plugin>
    59. <groupId>org.springframework.bootgroupId>
    60. <artifactId>spring-boot-maven-pluginartifactId>
    61. plugin>
    62. plugins>
    63. build>
    64. project>

  • 相关阅读:
    标点符号应该占在作文本的什么位置
    K8S:配置资源管理 Secret和configMap
    国内领先的五大API接口供应商
    STM32 使用内部晶振导致 Can 通讯异常
    【R语言文本挖掘】:tidy数据格式及词频计算
    异常解决!前后端交互时,CORS跨域问题的解决过程
    Linux防火墙配置
    LeetCode刷题笔记之图论
    安卓Unity3D Camera图像和音频采集推送代码
    内存取证系列5
  • 原文地址:https://blog.csdn.net/m0_64818669/article/details/126097068