后端——》springboot集成nacos+dubbo实现RPC调用

写在前面

服务器有个定时任务,需要进行大批量的接口请求和数据操作,最大线程数拉满了,仍不能满足要求,因为服务器硬件核心数就摆在那。

最多能并发的线程就 内核个数*2,即所谓的核心线程数,其他的线程会被放到线程数中等待执行,看似开了 200个线程,其实大多是心理安慰😂

代码逻辑已经优化的不能再优化了,只好考虑横向扩展了,即增加一台机器执行,分散服务器的压力。两台服务器执行同一个任务,那么在相同的时间范围内,能传输的数据 肯定比在单台服务器上要多。

遍观各项技术架构,dubbo 似乎是不可或缺的组件,它可以让不同服务器之间的程序进行远程RPC调用,且消耗资源要比 RESTful小。同时搭配nacos的注册中心,简直是绿茶配青梅,天生是一对。

说干就干,于是,这无数的坑就来了...

那,dubbo和nacos是什么呢?下面是个比喻

当你去餐厅吃饭,Dubbo 就像服务员,Nacos 就像菜单和餐厅的接待台。

  • Dubbo(服务员):Dubbo 就像服务员,它帮助你点菜,把你的点餐信息传递给厨房,并把菜端到你的桌子上。它协调不同的服务,确保你的请求被满足。
  • Nacos(菜单和接待台):Nacos 就像菜单,上面列出了餐厅提供的各种菜肴,以及它们的价格和描述。同时,Nacos也是接待台,你可以在那里获取餐厅的地址、联系信息,以及了解特别优惠和促销信息。

将Dubbo和Nacos结合起来,就像在餐厅里有一个聪明的服务员(Dubbo)拿着菜单(Nacos)帮助你点菜、协调厨房和为你提供更多关于餐厅的信息。这使你能够轻松享受美食而不必亲自处理所有细节。

步骤

我的目标是是这样的 让部署在 服务器A上的消费者C1 能同时调用 服务器A 上的提供者 P1 ,和服务器B上的提供者 P2

网上的攻略,看似很难,实则不简单...

需要一台开发机(我的是windwos)用于部署 消费者1(简称 C1)和提供者1(简称 P1),以及nacos,一台linux测试机,用来部署提供者2(简称 P2)。由于我要模拟跨服务调用,windwos上的nacos需要内网穿透,将注册中心的地址暴露给linux中的P2 供C1来调用。

一:nacos

nacos 是 SpringCloudAlibaba的一个注册和配置中心组件

Nacos /nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service的首字母简称,一个更易于构建云原生应用的动态服务发现、配置管理和服务管理平台。Nacos 致力于帮助您发现、配置和管理微服务。

Nacos 提供了一组简单易用的特性集,帮助您快速实现动态服务发现、服务配置、服务元数据及流量管理。Nacos 帮助您更敏捷和容易地构建、交付和管理微服务平台。

Nacos 是构建以"服务"为中心的现代应用架构 (例如微服务范式、云原生范式) 的服务基础设施。

不多逼逼,直接下载运行。

下载链接:github.com/alibaba/nac...

下载zip压缩包,解压,找到 bin目录下的startup.cmd,编辑,把下图的地方改为 standalone

双击 startup.cmd ,nacos会以单机模式启动。(与之对应的是集群模式,我以后用到了再回来修改)

启动成功 会弹出一些命令行,如下图所示。程序运行的过程中要保持这个窗口,不要随手关掉了。(也可以创建个服务 后台运行)

二:内网穿透

上面的nacos在我本地启动后,可以通过命令行中的网址10.239.20.202:8848/nacos/index.html访问到 nacos控制台页面。

同时我的代码内也可以通过配置 10.239.20.202:8848 这个ip端口访问nacos程序。

但是,上面的 10.239.20.202是我本地内网的ip,如果另一台机器上的程序跟当前机器不处于同一局域网,那么就访问不到 部署在我本地的 nacos注册中心了。

(注:实际上这也是nacos组件的原意,它不希望注册中心对外开放,它推荐在内网即同一局域网内使用,各服务通过内网ip注册调用)

但我们就是头铁,偏要逆水行舟。所以我们需要做内网穿透,将本地nacos注册中心的地址暴露出来。内网穿透大家都会使用,我推荐使用NATAPP,不推荐花生壳。

这一步也是挺坑的一步,最初因为这一步卡壳了很久。springboot+dubbo 的配置文件中的注册中心 ip:port格式,所以我下意识的认为 我应该用tcp 协议的方式穿透,因为tcp协议穿透出来的网址就是ip:port格式。配置上去后 要么是消费者找不到提供者方法,要么是服务列表找不到服务,要么是双双掉线。一大串儿问题。

正确的做法是,使用web协议穿透,然后我们在配置文中的port中手动添加端口号为80,得到一个 ip:80的可供外网调用的ip端口。

三:dubbo

dubbo 也是 SpringCloudAlibaba的一个组件,用于rpc调用的。

调用方 称之为 消费者,被调用方 称之为 提供者。

讲到dubbo,就涉及到代码了,我们先来看看项目结构。

项目模块从上往下 依次 是 公共类、消费者、提供者。

公共类中存放一些 消费者和提供者都可能用到的类,比如entity,公共参数等等。

接口类 interface也会定义在公共类中,由消费者调用,由提供者实现。

具体一点就是:

在公共类定义 doSomeThingService

在提供者实现这个service,doSomeThingImpl上添加注解 @DubboService

在消费者注入这个service,不过不用@Autowired,而是用@DubboReference

如下:

公共类:

提供者:

消费者:

通过dubbo框架,可以让部署在A服务器上的消费者直接调用部署在B服务上的提供者方法。

四:springboot集成

公共类

一个接口类,平平无奇,无甚可讲

提供者

1、pom文件

xml 复制代码
<dubbo.version>2.7.13</dubbo.version>
<nacos.version>1.4.1</nacos.version>
xml 复制代码
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>${dubbo.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>${dubbo.version}</version>
</dependency>

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>${nacos.version}</version>
</dependency>

<!-- 解决dubbo2.7.13jar包冲突问题-->
<dependency>
    <groupId>com.alibaba.spring</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>1.0.11</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>${dubbo.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
        </exclusion>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

除了导入上面这4个包外,还需要依赖公共模块,公共模块是自定义的,上面就不展示了

2、配置文件 application.properties

ini 复制代码
server.port=8901
spring.application.name=tongcheng-provider
dubbo.registry.address=nacos://ujx58f.natappfree.cc:80
dubbo.registry.parameters.namespace=8deefd1b-0a2f-432a-b44b-195d5d3c7664
dubbo.protocol.name=dubbo
dubbo.protocol.port=20881
dubbo.provider.timeout=36000000

参数一一介绍

  1. port 是springboot程序的启动端口
  2. name 是模块的名字,也会展示在nacos的服务列表中
  3. address 是注册中心的地址,可以看到我使用的是nacos的注册中心,后面接的是内网穿透的地址
  4. namespace是命名空间,用于隔离不同的服务消费,可以理解成分组的功能。里面的值怎么来的可以看下图
  5. name=dubbo是nacos列表的配置分组
  6. port是注册nacos的端口号,干啥用的呢,就是供其他服务调用的时候用的,具体的调用及分配策略,是在nacos控制台设置的
  7. timeout是服务调用超时时间

nacos 控制台操作:1

创建一个命名空间,他会自动生成一串id,配到上面的namespace处。

3、启动类:

在启动类上添加一个注解 @EnableDubbo,如下图所示

同时再添加一个 EntityScan注解,用于扫描公共类中实体的位置,不然可能会报错。同时实体类需要序列化,即 implements Serializable,不然可能也会报错。

4、实现类

消费者

1、pom文件(与提供者相同)

xml 复制代码
<dubbo.version>2.7.13</dubbo.version>
<nacos.version>1.4.1</nacos.version>
xml 复制代码
<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-spring-boot-starter</artifactId>
    <version>${dubbo.version}</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo-registry-nacos</artifactId>
    <version>${dubbo.version}</version>
</dependency>

<dependency>
    <groupId>com.alibaba.nacos</groupId>
    <artifactId>nacos-client</artifactId>
    <version>${nacos.version}</version>
</dependency>

<!-- 解决dubbo2.7.13jar包冲突问题-->
<dependency>
    <groupId>com.alibaba.spring</groupId>
    <artifactId>spring-context-support</artifactId>
    <version>1.0.11</version>
</dependency>

<dependency>
    <groupId>org.apache.dubbo</groupId>
    <artifactId>dubbo</artifactId>
    <version>${dubbo.version}</version>
    <exclusions>
        <exclusion>
            <groupId>org.springframework</groupId>
            <artifactId>spring</artifactId>
        </exclusion>
        <exclusion>
            <groupId>javax.servlet</groupId>
            <artifactId>servlet-api</artifactId>
        </exclusion>
    </exclusions>
</dependency>

2、配置文件 application.properties

ini 复制代码
server.port=8080
spring.application.name=manage-system
dubbo.registry.address=nacos://ujx58f.natappfree.cc:80
dubbo.registry.parameters.namespace=8deefd1b-0a2f-432a-b44b-195d5d3c7664
dubbo.protocol.name=dubbo
dubbo.protocol.port=-1
dubbo.provider.timeout=36000000

配置文件跟提供者也差不多,就两个port要变化,springboot程序的端口号要变,注册nacos的端口号要改成-1.

当你的dubbo.protocol.port配置为-1时,Dubbo将在运行时动态选择一个可用的端口,并在注册中心(如ZooKeeper或Nacos)中注册服务时使用这个端口信息。这有助于避免端口冲突,特别是在多个Dubbo服务运行在同一台机器上或在不同的开发/测试环境中时。

其他的配置文件就于提供者一样了

3、启动类

启动类同上,添加@EnableDubbo注解,表示支持dubbo的注释。

4、调用

在需要远程调用的类,使用注解 @DubboReference 引入公共接口类。

然后在方法中,直接用调用就公共接口类中的方法就OK了,感觉就像 @Autowired引入的方法一样,很丝滑。

控制台

经过上面的代码,此时提供者和消费者都有了,为了模拟分布式操作,启动两份提供者代码。把提供者copy1份,改一下端口号,并修改程序名为tongcheng-provider2,然后先启动提供者,再启动消费者。

等三个程序都启动成功后,打开nacos控制台(http://内网ip:8848/nacos/index.html)

可以看到菜单=》服务管理=》服务列表中有 消费者和提供者了。消费者1个,提供者2个,如下。

点击 提供者操作栏的详情,可以看到 提供者下有两个ip,第一个是部署在我windwos本机的提供者1的内网ip,第二个是部署在linux服务器的提供者2的外网ip(马赛克了)。

部署在我windows本机的消费者现在可以同时调用到 提供者1和提供者2,默认按1:1的权重轮询调用,权重也可以在后面的编辑中配比。

当点击其中一台提供者后面的下线按钮后,消费者会默认访问另外在线的一台提供者。

此时nacos+dubbo的远程调用的基本功能就已经实现了。

写在后面

上面的操作只解决了调用问题。其实文中可以看到,消费者是一个定时任务,那前方还有很多坑在等着我,比如:redis分布式锁的问题,分布式定时任务的并发的问题等等,后面会再持续更新...

特此记录,已备后用。

相关推荐
paopaokaka_luck4 小时前
【360】基于springboot的志愿服务管理系统
java·spring boot·后端·spring·毕业设计
码农小旋风5 小时前
详解K8S--声明式API
后端
Peter_chq5 小时前
【操作系统】基于环形队列的生产消费模型
linux·c语言·开发语言·c++·后端
Yaml46 小时前
Spring Boot 与 Vue 共筑二手书籍交易卓越平台
java·spring boot·后端·mysql·spring·vue·二手书籍
小小小妮子~6 小时前
Spring Boot详解:从入门到精通
java·spring boot·后端
hong1616886 小时前
Spring Boot中实现多数据源连接和切换的方案
java·spring boot·后端
aloha_7896 小时前
从零记录搭建一个干净的mybatis环境
java·笔记·spring·spring cloud·maven·mybatis·springboot
睡觉谁叫~~~7 小时前
一文解秘Rust如何与Java互操作
java·开发语言·后端·rust
茶馆大橘8 小时前
微服务系列五:避免雪崩问题的限流、隔离、熔断措施
java·jmeter·spring cloud·微服务·云原生·架构·sentinel
2401_865854889 小时前
iOS应用想要下载到手机上只能苹果签名吗?
后端·ios·iphone