Java62分布式RPC框架Dubbo

Posted 码农编程录

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Java62分布式RPC框架Dubbo相关的知识,希望对你有一定的参考价值。


1.RPC

RPC:远程过程调用,我这台电脑调用一个函数,这个函数在另一个电脑上执行。这种方式就像是本地正常的一次函数一样,不需要关注远程(网络连接,断开,传数据)细节。 如下a和b两个参数打包发给服务端。

1.为什么远程remote?本机运行的程序主要干的事是A,执行A的过程需要借助B功能,但是B功能不属于A功能范围内事情。所以我们会调实现B功能的集群,获取它们计算出来的结果。请求和响应和HTTP协议很像,grpc谷歌框架就是使用了http协议。

3 .数据包该如果封?程序内存中数据结构封装到传输时数据结构(文本或字节数组),传来后还要将数据(即字节或文本)恢复到内存中,这传一次就叫做序列化和反序列化。HTTP中json等就是序列化方式,一个数据在内存中的表达可能没法直接给人看的,或者没法直接两个进程间无法互相阅读的,除了共享内存。json和xml都是文本化的序列化方式,高效的grpc中一般不会用json这种序列化方式,比如用jdk自己的序列化方式,protobuf等。

4 .如果需要提高rpc性能的话除了序列化和反序列化,数据传输过程中需要提高网络IO性能。网络IO中涉及很多的系统调用,有对这些系统调用较好的封装如java中有名的rpc框架dubbo。dubbo中使用netty作为网络传输的一个框架实现,netty又是基于java的NIO,NIO最终调用一些系统调用,这些系统调用能够实现网络传输过程中零拷贝,多路复用等等充分提高了网络性能。
在这里插入图片描述

2.软件演进

单体架构:一个tomcat正常200并发量。
在这里插入图片描述
垂直架构:每个系统独立,通过复制通讯。
在这里插入图片描述
SOA架构:rpc调用,如果商品服务用的最多,撑不起那么大流量了,把商品服务再部署一份,怎么能保证其它系统调用把请求均匀分散到多个服务上去呢?也要实现负载均衡。
在这里插入图片描述
微服务架构:更多服务器。
在这里插入图片描述

3.Dubbo和注册中心zookeeper

Container相当于tomcat容器或spring ioc容器。
Provider就是服务提供者,业务逻辑的实现。
Registry相当于菜单(挂了没事,本地会缓存一份)。
Monitor监控应用程序调用了多少次,响应的速度是不是够快,都能进行监控。
在这里插入图片描述
Dubbo官方推荐使用Zookeeper(像数据库一样,目录树状结构)作为服务注册中心。其它的dubbo支持的注册中心有:redis、nacos。
在这里插入图片描述
zookeeper软件使用:第一步:下载地址:http://archive.apache.org/dist/zookeeper/
第二步:把 zookeeper 的压缩包(zookeeper-3.4.6.tar.gz)上传到 linux 系统。
第三步:解压缩压缩包:tar -zxvf zookeeper-3.4.6.tar.gz。
第四步:进入zookeeper-3.4.6目录,创建data目录。
第五步:进入conf目录 ,把zoo_sample.cfg 改名为zoo.cfg:mv zoo_sample.cfg zoo.cfg。
第六步:打开zoo.cfg文件, 修改data属性:dataDir=/usr/zookeeper-3.4.6/data。

进入Zookeeper的bin目录,启动服务命令 : ./zkServer.sh start。
停止服务命令:./zkServer.sh stop 。
查看服务状态命令:./zkServer.sh status 。ps -ef|grep zookeeper。

4.Dubbo创建接口工程

serviceImpl = Provider 。Controller = Consumer 。
在这里插入图片描述
File-New-Project-Maven
在这里插入图片描述

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
         xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.itheima.dubbo</groupId>
    <artifactId>dubbo-interface</artifactId>
    <version>1.0-SNAPSHOT</version>    
    <packaging>jar</packaging>   <!--java工程打包方式为jar-->
    
    <description>定义业务接口</description>
</project>

在这里插入图片描述

package com.itheima.dubbo;

public interface HelloService { //定义接口
    String say(String name);
}

如下点击后就不用管了,把整个项目打成jar包后即安装到了maven仓库。
在这里插入图片描述

5.Dubbo创建服务提供者(Provider)

用tomcat运行业务实现,所以创建web工程。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.itheima.dubbo</groupId>
  <artifactId>dubbo-provider</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>   <!--web工程打war包-->

  <name>dubbo-provider Maven Webapp</name>

  <properties>
    <spring.version>5.0.5.RELEASE</spring.version>    <!--版本-->
  </properties>

  <dependencies>
    <dependency>  <!--导入dubbo-interface的jar包-->
      <groupId>com.itheima.dubbo</groupId>
      <artifactId>dubbo-interface</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>
    
    <dependency>  <!--导入dubbo和spring相关的jar包-->
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <!-- dubbo相关 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.0</version>
    </dependency>
    
    <dependency>
      <groupId>org.apache.zookeeper</groupId>
      <artifactId>zookeeper</artifactId>
      <version>3.4.7</version>
    </dependency>
    
    <dependency>
      <groupId>com.github.sgroschupf</groupId>
      <artifactId>zkclient</artifactId>
      <version>0.1</version>
    </dependency>
    
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>fastjson</artifactId>
      <version>1.2.47</version>
    </dependency>
    
    <!--数据库驱动-->
    <dependency>
      <groupId>mysql</groupId>
      <artifactId>mysql-connector-java</artifactId>
      <version>5.1.47</version>
    </dependency>
    
    <!--数据库连接池-->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>druid</artifactId>
      <version>1.1.6</version>
    </dependency>
    
    <!--mybatis-->
    <dependency>
      <groupId>org.mybatis</groupId>
      <artifactId>mybatis-spring</artifactId>
      <version>1.3.2</version>
    </dependency>
  </dependencies>
</project>
package com.itheima.service.impl;
import com.alibaba.dubbo.config.annotation.Service;
import com.itheima.dubbo.HelloService;
import org.springframework.transaction.annotation.Transactional;

@Service(interfaceClass = HelloService.class)
@Transactional
public class HelloServiceImpl implements HelloService { 
//业务逻辑,把它发布成服务才行,发布服务依赖dubbo,因为dubbo实现了远程调用,实现了comsumer调用provide。
//所以dubbo配置也需要,也要下载一些dubbo相关的jar包。
    public String say(String s) {
        System.out.println("=====我被调用了");
        return "say hi " + s;
    }
}

如上普通工程变成了dubbo工程,接下来怎么通过dubbo将服务发布出去,需要将spring和dubbo进行集成,集成文件如下。

//dubbo-provider.xml
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
       xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xmlns:p="http://www.springframework.org/schema/p"
       xmlns:context="http://www.springframework.org/schema/context"
       xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
       xmlns:mvc="http://www.springframework.org/schema/mvc" xmlns:dubdo="http://code.alibabatech.com/schema/dubbo"
       xmlns:tx="http://www.springframework.org/schema/tx"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
		http://www.springframework.org/schema/beans/spring-beans.xsd
         http://www.springframework.org/schema/mvc
         http://www.springframework.org/schema/mvc/spring-mvc.xsd
         http://code.alibabatech.com/schema/dubbo
         http://code.alibabatech.com/schema/dubbo/dubbo.xsd
         http://www.springframework.org/schema/context
         http://www.springframework.org/schema/context/spring-context.xsd http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx.xsd">

    <!-- 当前应用名称。用于注册中心计算应用间依赖关系,注意:消费者和提供者应用名不要一样 -->
    <dubbo:application name="dubbo-provider" />

    <!-- 连接服务注册中心zookeeper ip为zookeeper所在服务器的ip地址,
     需要先开启zookeeper,默认2181端口,可在.cfg文件里修改端口。注册信息保存到zookeeper里了-->
    <dubbo:registry address="zookeeper://127.0.0.1:2181"/>

    <!-- 消费者和提供者通讯:协议(数据结构的约定)和port:端口默认是20880,协议有rmi,rest,http -->
    <dubbo:protocol name="dubbo" port="20881"></dubbo:protocol>

    <!-- 扫描指定包,加入@Service注解的类会被发布为服务
        1.路径匹配package
        2.类上使用了@Service注解
     -->
    <dubbo:annotation package="com.itheima.service.impl" />  <!--哪个目录下的类被发布为服务-->
</beans>

怎么启动这个服务呢?我们使用了spring,通过加载spring容器读进来才能启动服务。如下配置context指定加载spring路径,通过listener创建ioc容器,启动还要指定tomcat。

//web.xml
<!DOCTYPE web-app PUBLIC
 "-//Sun Microsystems, Inc.//DTD Web Application 2.3//EN"
 "http://java.sun.com/dtd/web-app_2_3.dtd" >
<web-app>
  <display-name>Archetype Created Web Application</display-name>
  
  <context-param>
    <param-name>contextConfigLocation</param-name>
    <param-value>classpath:dubbo-provider.xml,classpath:applicationContext-dao.xml</param-value>
  </context-param>
  
  <listener>
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class>
  </listener>
</web-app>

在这里插入图片描述
点击绿色+号Tomcat Server - local。
在这里插入图片描述

6.Dubbo创建服务消费者(Consumer)

创建服务消费者(springmvc)工程,服务消费者调用服务提供者。先创建web工程步骤如上。
在这里插入图片描述

//pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
  xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.itheima.dubbo</groupId>
  <artifactId>dubbo-comsumer</artifactId>
  <version>1.0-SNAPSHOT</version>
  <packaging>war</packaging>

  <name>dubbo-comsumer Maven Webapp</name>
  <!-- FIXME change it to the project's website -->
  <url>http://www.example.com</url>

  <properties>
    <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    <maven.compiler.source>1.7</maven.compiler.source>
    <maven.compiler.target>1.7</maven.compiler.target>
    <spring.version>5.0.5.RELEASE</spring.version>
  </properties>

  <dependencies>
    <!--注意: 在消费者引入,需要调用业务逻辑的接口-->
    <dependency>
      <groupId>com.itheima.dubbo</groupId>
      <artifactId>dubbo-interface</artifactId>
      <version>1.0-SNAPSHOT</version>
    </dependency>

    <!--spring相关-->
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-beans</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-webmvc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-aspects</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-context-support</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <dependency>
      <groupId>org.springframework</groupId>
      <artifactId>spring-jdbc</artifactId>
      <version>${spring.version}</version>
    </dependency>
    
    <!-- dubbo相关 -->
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>dubbo</artifactId>
      <version>2.6.0</version>
    </dependency>
    
    以上是关于Java62分布式RPC框架Dubbo的主要内容,如果未能解决你的问题,请参考以下文章

Java23maven加强,分布式RPC框架Dubbo

Java RPC 分布式框架性能大比拼,Dubbo排老几?

大牛带你深入Dubbo,高性能RPC通信框架:Dubbo简介和总体大图

基于java消息队列的分布式RPC开源框架

转载分布式RPC框架性能大比拼

Dubbo高性能轻量级的开源Java RPC框架