• SofaBoot使用Nacos进行服务注册发现


    前提

    最近创业公司的项目组基于业务需要,开发一套新的微服务,考虑到选用的组件必须是主流、社区活跃、生态完善以及方便迁移到云上等因素,引入了SOFAStack全家桶。微服务开发里面,一个很重要的功能就是服务发现与注册,笔者花了点时间做了一个SOFABootSOFARpc结合Nacos实现微服务发现注册与远程调用的示例。

    依赖版本踩坑

    笔者花了点时间去尝试SOFABootSOFARpc结合Nacos客户端的依赖版本关系,截止本文编写完成的时候(2020-01-01),sofaboot-dependencies的最新版本为3.2.1,对应于SOFABoot-3.2.1SOFARpc-5.6.3SpringBoot-2.1.x.RELEASE。在这两个最新版本的项目中,无论引入什么版本的nacos-clinet,都没有办法向Nacos-Server注册服务信息。关于这一点,笔者曾经从Issues里面查找相关的内容,暂时无果,于是把示例项目分享给社区的大佬进行分析,如果有解决方案,会在这篇博文中更新。试出来的可用的版本组合为:

    • sofaboot-dependencies:3.2.0
    • spring-boot-dependencies:2.1.0.RELEASE
    • nacos-api:0.6.0nacos-client:0.6.0

    引入依赖如下:

    <properties>
        <sofa.boot.version>3.2.0</sofa.boot.version>
        <spring.boot.version>2.1.0.RELEASE</spring.boot.version>
        <nacos.version>0.6.0</nacos.version>
    </properties>
    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-dependencies</artifactId>
                <version>${spring.boot.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
            <dependency>
                <groupId>com.alipay.sofa</groupId>
                <artifactId>sofaboot-dependencies</artifactId>
                <version>${sofa.boot.version}</version>
                <scope>import</scope>
                <type>pom</type>
            </dependency>
        </dependencies>
    </dependencyManagement>
    <dependencies>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>healthcheck-sofa-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alipay.sofa</groupId>
            <artifactId>rpc-sofa-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-client</artifactId>
            <version>${nacos.version}</version>
        </dependency>
        <dependency>
            <groupId>com.alibaba.nacos</groupId>
            <artifactId>nacos-api</artifactId>
            <version>${nacos.version}</version>
        </dependency>
    </dependencies>
    

    编写服务提供方和服务消费方代码

    这里有一个前提,需要启动一个Nacos-Server,为了方便起见,使用单机模式本地启动即可,那么服务注册的地址就是http://127.0.0.1:8848。示例项目的结构如下:

    ├─src
    │  └─main
    │      ├─java
    │      │  └─club
    │      │      └─throwable
    │      │          ├─client
    │      │          │      ClientApplication.java
    │      │          │      
    │      │          ├─contract
    │      │          │      HelloService.java
    │      │          │      
    │      │          └─server
    │      │                 DefaultHelloService.java
    │      │                 ServerApplication.java
    │      │                  
    │      └─resources
    │              application-client.properties
    │              application-server.properties
    

    其中contract为契约包,可以提供给客户端和服务端使用,client包里面编写客户端(comsumer)的代码,而server包里面编写服务端(provider)的代码。

    契约接口HelloService很简单:

    public interface HelloService {
    
        String sayHello(String name);
    }
    

    服务提供方需要实现此接口,实现类是DefaultHelloService

    @Service
    @SofaService(interfaceType = HelloService.class, bindings = {
            @SofaServiceBinding(bindingType = "bolt")
    })
    public class DefaultHelloService implements HelloService {
    
        @Override
        public String sayHello(String name) {
            return String.format("%s say hello!", name);
        }
    }
    

    这里使用的服务协议绑定类型为bolt,是官方示例建议的协议,当然还有dubbohttp等等,可以混合配置。接着编写服务提供方启动类ServerApplication

    @SpringBootApplication(scanBasePackages = {"club.throwable.server", "club.throwable.contract"})
    public class ServerApplication {
    
        public static void main(String[] args) {
            SpringApplication.run(ServerApplication.class, args);
        }
    }
    

    服务提供方应用的配置文件application-server.properties如下:

    spring.application.name=sofa-rpc-provider
    server.port=9092
    # 用Nacos做注册中心
    com.alipay.sofa.rpc.registry-address=nacos://127.0.0.1:8848
    

    使用spring.profiles.active=server启动ServerApplication,启动成功后用浏览器打开Nacos-Console

    可见目前sofa-rpc-provider服务已经成功注册到Nacos-Server。接着编写客户端代码,为了方便起见,所有的代码编写在启动类ClientApplication

    @Slf4j
    @SpringBootApplication(scanBasePackages = {"club.throwable.client", "club.throwable.contract"})
    public class ClientApplication implements CommandLineRunner {
    
        @SofaReference(binding = @SofaReferenceBinding(bindingType = "bolt"))
        private HelloService helloService;
    
        public static void main(String[] args) {
            SpringApplication.run(ClientApplication.class, args);
        }
    
        @Override
        public void run(String... args) throws Exception {
            log.info("调用HelloService#sayHello(),结果:{}", helloService.sayHello("throwable"));
        }
    }
    

    服务消费方的配置文件application-client.properties如下:

    spring.application.name=sofa-rpc-consumer
    server.port=9091
    # 用Nacos做注册中心
    com.alipay.sofa.rpc.registry-address=nacos://127.0.0.1:8848
    

    使用spring.profiles.active=client启动ClientApplication,启动完成后控制台输出:

    2020-01-02 17:07:58.782  INFO 2900 --- [main] club.throwable.client.ClientApplication  : 调用HelloService#sayHello(),结果:throwable say hello!
    

    基本原理如下:

    小结

    SOFABootSOFARpc底层依赖于Spring容器,可以跟随SpringBoot版本迭代升级,底层通讯使用Netty,在性能上有保障,而且真正做到了兼容HTTPDubboService Mesh(后面应该会把Service Mesh作为通讯协议进行兼容)等等协议,对于开发者而言相对友好,学习成本低,做到真正的开箱添加少量配置即可使用。除了目前发现依赖版本的问题,暂时没有大的坑,尝尝鲜的感觉还是挺不错的。

    示例项目:

    原文链接

    (本文完 c-1-d e-a-20200101)

    技术公众号(《Throwable文摘》),不定期推送笔者原创技术文章(绝不抄袭或者转载):

    娱乐公众号(《天天沙雕》),甄选奇趣沙雕图文和视频不定期推送,缓解生活工作压力:

  • 相关阅读:
    python修改python unittest的运行顺序
    史上最强大的python selenium webdriver的包装
    第六种方式,python使用cached_property缓存装饰器和自定义cached_class_property装饰器,动态添加类属性(三),selnium webdriver类无限实例化控制成单浏览器。
    python带参装饰器的改良版
    第五种方式,python使用组合来添加类方法和属性(二),以selenium的webdriver为例
    python装饰器、继承、元类、mixin,四种給类动态添加类属性和方法的方式(一)
    linux添加PYTHONPATH环境变量
    linux 按照端口一句命令杀死进程,按照进程名称一句命令杀死进程
    python __all__用法
    使用pycharm,追求最优的代码。
  • 原文地址:https://www.cnblogs.com/throwable/p/12134270.html
Copyright © 2020-2023  润新知