学习之前,确保有以下知识基础:

  • Java网络编程
  • Socket传输数据
  • IO流

rpc简介及实现

rpc是remote procedure call的简写,意思为远程过程调用。

rpc应用较多的情景是分布式开发,那什么是分布式开发呢?

原本我也是想自己解释的,奈何网上大佬解释得很清楚了,这里就不献丑了,建议阅读完下面推荐的几篇再继续往下

刚开始的时候,服务和调用都是在同一机器,这叫本地过程调用

之后,由于客户量增长,一个服务器并不能满足要求,之后便是把调用和服务分开,分别部署在不同的机器,负责调用服务方法的称之为客户机,负责提供服务方法的称为服务机

上图的原理可能步骤有点多,但是只要记住一点,客户机是把数据通过Socket或者是其他协议传递到了服务机,让服务机进行处理,从而以相同的协议方式把数据传递回来

如何实现一个简单的RPC一文中,大佬已经实现了一个简洁的rpc框架,然后对于这个rpc框架,并提出来的一些可以优化的点:

1. 缺乏通用性

我通过给Calculator接口写了一个CalculatorRemoteImpl,来实现计算器的远程调用,下一次要是有别的接口需要远程调用,是不是又得再写对应的远程调用实现类?这肯定是很不方便的。

2、集成Spring

在实现了代理对象通用化之后,下一步就可以考虑集成Spring的IOC功能了,通过Spring来创建代理对象,这一点就需要对Spring的bean初始化有一定掌握了。

3、长连接or短连接

总不能每次要调用RPC接口时都去开启一个Socket建立连接吧?是不是可以保持若干个长连接,然后每次有rpc请求时,把请求放到任务队列中,然后由线程池去消费执行?只是一个思路,后续可以参考一下Dubbo是如何实现的。

4、 服务端线程池

我们现在的Server端,是单线程的,每次都要等一个请求处理完,才能去accept另一个socket的连接,这样性能肯定很差,是不是可以通过一个线程池,来实现同时处理多个RPC请求?同样只是一个思路。

5、服务注册中心

正如之前提到的,要调用服务,首先你需要一个服务注册中心,告诉你对方服务都有哪些实例。Dubbo的服务注册中心是可以配置的,官方推荐使用Zookeeper。如果使用Zookeeper的话,要怎样往上面注册实例,又要怎样获取实例,这些都是要实现的。

6、负载均衡

如何从多个实例里挑选一个出来,进行调用,这就要用到负载均衡了。负载均衡的策略肯定不只一种,要怎样把策略做成可配置的?又要如何实现这些策略?同样可以参考Dubbo,Dubbo - 负载均衡

7、结果缓存

每次调用查询接口时都要真的去Server端查询吗?是不是要考虑一下支持缓存?

8、多版本控制

服务端接口修改了,旧的接口怎么办?

9、异步调用

客户端调用完接口之后,不想等待服务端返回,想去干点别的事,可以支持不?

10、优雅停机

服务端要停机了,还没处理完的请求,怎么办?

PS:使用rpc的时候,需要考虑到网络问题,需要采用重试机制

由上述的这些问题,之后便是出现了一些优秀的rpc框架,如dubbo、spring cloud等

dubbo简介

Dubbo是阿里巴巴开源的基于 Java 的高性能 RPC(远程过程调用) 分布式服务框架(SOA),致力于提供高性能和透明化的RPC远程服务调用方案,以及SOA服务治理方案,其内部使用了 Netty、Zookeeper,保证了高性能高可用性。

dubbo结构图:

节点 角色说明
Provider 暴露服务的服务提供方
Consumer 调用远程服务的服务消费方
Registry 服务注册与发现的注册中心
Monitor 统计服务的调用次数和调用时间的监控中心
Container 服务运行容器

其中,注册中心Registry和监控中心Monitor都是可选的,所以,我们下文先简单实现dubbo(点对点传输数据)

<dependency>
<groupId>com.starsone</groupId>
<artifactId>dubbo-api</artifactId>
<version>0.0.1</version>
</dependency>

dubbo简单实现

项目说明:

项目基于spring boot,分为三个部分,apiconsumerprovider

  • api主要是用来声明一些服务的接口(maven项目)
  • provider则是对服务接口的具体实现(spring boot项目,通过maven依赖api项目)
  • consumer则是远程调用provider提供的服务接口(spring boot项目,通过maven依赖api),

本质上consumer相当于客户机,而provider相当于客户机

1.新建项目

使用IDEA,建立一个空白的项目,之后新建module

之后IDEA会弹出一个新建module的窗口

依次新建api、provider、cousmer三个module

api选择maven项目,之后填写相关的包名信息直接新建即可(不需要选择具体的maven结构),而另外两个则是spring boot项目,选择spring initializr新建即可,同样,不要勾选其他的依赖,填写好包名相关信息新建即可

2.api项目声明服务接口

在api项目中,我们新建一个CalculatorService接口,里面定义一个add的方法

public interface CalculatorService {
int add(int a,int b);
}

3.配置api项目的依赖

原本,之后的provider和consumer项目都是需要引用dubbo-spring-boot-starter这个依赖,dubbo-spring-boot-starter依赖中已经包含了dubbo依赖,这样就可以不需要写dubbo的依赖了

由于之后我们的provider和consumer项目都是需要引用api这个项目,所以,我们可以把provider和consumer所需要的依赖dubbo-spring-boot-starter添加到api这个项目中

之后的provider和consumer项目也就是依赖了api项目,也成功依赖了dubbo-spring-boot-starter

<dependency>
<groupId>org.apache.dubbo</groupId>
<artifactId>dubbo-spring-boot-starter</artifactId>
<version>2.7.5</version>
</dependency>

4.provider和consumer项目引用api项目依赖

由于之前我们创建的api项目是maven项目,所以添加依赖就很简单,在provider和consumer各自的pom.xml添加依赖即可

5.provider实现api中的服务接口

我们在provider项目中新建一个类CalculatorServiceImpl,去实现CalculatorService接口

@Service(interfaceName = "calculatorService")
class CalculatorServiceImpl:CalculatorService {
override fun add(a: Int, b: Int): Int {
val result = a+b
println("$a+$b=$result")
return result
}
}

注意,这里的Service注解是dubbo包里面的注解,而不是spring中的Service,定义接口名interfaceNamecalculatorService,方便之后容器进行查找

6.配置provider项目

我们需要修改spring boot的配置文件,这里我使用yml的形式进行配置,阅读比较舒适

spring:
application:
name: dubbo-provider-application
dubbo:
scan:
#扫描指定包是否包含有dubbo中Service注解的类
base-packages: com.starsone.provider.service
protocol:
name: dubbo #协议,默认为dubbo(其他协议webserovice、Thrift、Hessain、http)
port: 12345 #端口,默认为20880
registry:
address: N/A #不需要注册中心

PS:如果不想在配置文件制定扫描包含有Service注解的类,可以在provider项目中的application类中添加开启dubbo自动扫描的注解@EnableDubbo

provider项目结构图:

7.运行provider

由于我们没有引入注册中心,所以得先运行provider,获得ip地址

之后consumer项目中,才能让springr容器去根据ip地址+端口号去找到对应的实例并自动装载

由输出日志,我们可以看到ip地址

8.consumer获得service对象

@Component
class MyRunner:ApplicationRunner {
@Reference(url ="dubbo://192.168.52.1:12345",interfaceName = "calculatorService" )
private lateinit var calculatorService: CalculatorService override fun run(args: ApplicationArguments?) {
println(calculatorService.add(5,14))
}
}

这里,由于是为了简单考虑,没有使用web依赖,所以,使用了ApplicationRunner这个接口进行测试,spring容器在加载完成会自动回调此接口

Reference注解是dubbo中的注解,consumer项目运行之后,consumer中的dubbo就会根据此url和一些其他的信息进行数据的传递,远程调用provider中的服务,之后,provider接收数据并进行处理,返回数据给consumer,是不是有了rpc的感觉?

9.配置consumer及测试

配置的话,只配置了应用的名称

之后,我们运行consumer的application,可以看到结果

同样,在provider项目,也是打印出了consumer项目传递过来的参数

引入注册中心

前面的实现,是没有注册中心的,属于一种直连的方式,但是,实际上,分布式开发,具有多台服务机

客户机应该是向注册中心请求,由注册中心查询当前空闲的服务机,并根据某种策略,选择其中一台服务机,将其ip地址返回给客户机,之后客户机通过ip地址,与该服务机进行连接,进行rpc操作

dubbo框架中,推荐使用ZooKeeper作为注册中心

ZooKeeper是一个分布式的,开放源码的分布式应用程序协调服务,是Google的Chubby一个开源的实现,是Hadoop和Hbase的重要组件。它是一个为分布式应用提供一致性服务的软件,提供的功能包括:配置维护、域名服务、分布式同步、组服务等。

1.下载zookeeper

http://mirror.bit.edu.cn/apache/zookeeper/

注意,这里下载的版本最好与项目中的依赖版本一致

2.导入zookeeper依赖

我们需要修改api项目中的依赖,这样provider和consumer两个项目的依赖也是得以修改

<dependency>
<groupId>org.apache.zookeeper</groupId>
<artifactId>zookeeper</artifactId>
<version>3.4.14</version>
<exclusions>
<exclusion>
<groupId>org.slf4j</groupId>
<artifactId>slf4j-log4j12</artifactId>
</exclusion>
<exclusion>
<groupId>log4j</groupId>
<artifactId>log4j</artifactId>
</exclusion>
<exclusion>
<groupId>io.netty</groupId>
<artifactId>netty</artifactId>
</exclusion>
</exclusions>
</dependency> <!-- Zookeeper客户端 -->
<dependency>
<groupId>org.apache.curator</groupId>
<artifactId>curator-recipes</artifactId>
<version>4.2.0</version>
</dependency>

3.配置provider和consumer的注册中心

provider:

consumer:

4.取消consumer指定url

由于我们使用的是注册中心,所以,不需要指定url了,把Reference注解中的url删掉

5.运行zookeeper

解压下载的zookeeper压缩包,进入到conf目录,把zoo_sample.cfg文件改为zoo.cfg

进入bin目录,点击zkserver.cmd文件,运行zookeeper

6.运行provider和consumer

先运行provider,之后运行consumer,可以看到结果

本篇文章也是折腾了几天,参考了十几篇文章,一步步测试才弄成功,有些知识点并没有太深入,像dubbo控制台、监控中心等如何搭建,后期学习的时候再进行补充说明吧

参考

rpc框架dubbo学习入门及环境搭建(spring boot+Kotlin)的更多相关文章

  1. Spring Boot入门(一):搭建Spring Boot项目

    从本篇博客开始,我们开始进入Spring Boot的世界,它的出现使Spring的开发变得更加简洁,因此一经推出受到众多程序员的喜爱. 作为Spring Boot系列的第一篇博客,我们先来讲解下如何搭 ...

  2. Dubbo学习之简单环境搭建

    Dubbo服务的发展和作用: 首先,看下一般网站架构随着业务的发展,逻辑越来越复杂,数据量越来越大,交互越来越多之后的常规方案演进历程. 其次,当服务越来越多之后,我们需要做哪些服务治理? 最后,是d ...

  3. 01-S3C2440学习入门概念+环境搭建【转】

    本文转载自:http://blog.csdn.net/fengyuwuzu0519/article/details/54754812 一.心得: 这两年学过很多东西,有点杂,总感觉不够踏实,于是准备写 ...

  4. 前端框架vue学习笔记:环境搭建

    兼容性 不兼容IE8以下 Vue Devtools 能够更好的对界面进行审查和调试 环境搭建 1.nodejs(新版本的集成了npm)[npm是node包管理 node package manager ...

  5. 一个入门rpc框架的学习

    一个入门rpc框架的学习 参考 huangyong-rpc 轻量级分布式RPC框架 该程序是一个短连接的rpc实现 简介 RPC,即 Remote Procedure Call(远程过程调用),说得通 ...

  6. 新手嘛,先学习下 Vue2.0 新手入门 — 从环境搭建到发布

    Vue2.0 新手入门 — 从环境搭建到发布 转自:http://www.runoob.com/w3cnote/vue2-start-coding.html 具体文章详细就不搬了,步骤可过去看,我这就 ...

  7. Spring框架学习笔记(8)——spring boot+mybatis plus+mysql项目环境搭建

    之前写的那篇Spring框架学习笔记(5)--Spring Boot创建与使用,发现有多小细节没有提及,,正好现在又学习了mybatis plus这款框架,打算重新整理一遍,并将细节说清楚 1.通过I ...

  8. RPC 框架 Dubbo 从理解到使用(一)

    技术架构演变 单一应用架构 通俗地讲,"单体应用(monolith application)"就是将应用程序的所有功能都打包成一个独立的单元.当网站流量很小时,只需一个应用,将所有 ...

  9. JAVA WEB快速入门之环境搭建

    前言 我是一直致力于:.NET技术栈.WEB前端.架构设计相关的开发与管理工作,但因国内大环境影响及公司技术方向发生转变(由.NET全部转为JAVA),需要熟练掌握JAVA WEB相关的知识,故我也得 ...

随机推荐

  1. Warning: $HADOOP_HOME is deprecated. hadoop解决方法补充版

    下面的解决方案我亲自试了没有问题:可行,但是对于初学者来说肯定会有一个疑问:这个.bash_profile文件到底在哪呢:其实很简单: 当前用户的.bash_profile在/home/用户/下,系统 ...

  2. JS做深度学习3——数据结构

    最近在上海上班了,很久没有写博客了,闲下来继续关注和研究Tensorflow.js 关于深度学习的文章我也已经写了不少,部分早期作品可能包含了不少错误的认识,在后面的博文中会改进或重新审视. 今天聊聊 ...

  3. 吴裕雄--天生自然python学习笔记:Beautiful Soup 4.2.0模块

    Beautiful Soup 是一个可以从HTML或XML文件中提取数据的Python库.它能够通过你喜欢的转换器实现惯用的文档导航,查找,修改文档的方式.Beautiful Soup会帮你节省数小时 ...

  4. 秒搭Kubernetes之使用Rancher

    Rancher 在接触Docker和K8s的前阶段就耳闻目睹到Rancher,但是没有进一步接触过.直到将K8s搭建完成.才进一步了学习与实践Rancher. Rancher是简便易用的容器管理.其中 ...

  5. C# 输出&输入&类型强制转换

    输入字符串 String s; s=Console.ReadLine(); 输出字符串 Console.WritrLine(s); 输出分两种 ①占位符输出:Console.WriteLine(&qu ...

  6. 转:ZABBIX监控H3C设备的CPU和内存使用率

      由于最近监控的H3C路由器经常出现死机现象,SNMP获取不到数据,后面检查发现是CPU使用率过高,直接导致无法处理SNMP请求,所以需求来了,怎样通过SNMP监控H3C路由器的CPU和内存使用率? ...

  7. Linux用户与用户组的关系

    一.用户和用户组文件 1. /etc/passwd:所创建的用户账号和信息均存放在次文件中,所有用户可读取: 最后一个字段的值一般为/sbin/nologin,表示该账号不能用来登陆linux系统: ...

  8. 基于Blazor写一个简单的五子棋游戏

    写这个五子棋游戏,其实主要目的是想尝试一下微软新作Blazor.Blazor对于那些搞.NET的程序员,又想做一些前端工作,真的挺友好,不用一句JS就可搞定前端交互,美哉.现在已经有很流行的前端框架, ...

  9. sql -- 获取商品分类的最新销售情况

    表设计: 需求: 1.先找出各个分类中销售的最新日期 select prod_class,max(sales_date) as sn from prod_sales group by prod_cla ...

  10. 基于google earth engine的中等分辨率全国水质反演

    我写博客的工作不像论文,假大空,我们直接上干货,之所以取一个这么大的名字,当然是我们能做到的... 不多说,我们对全国水体进行水质参数反演,不用MODIS,太粗,我们直接用哨兵,这样就可以直接做到大型 ...