Dubbo基础学习记录

分类专栏:
dubbo相关

文章标签:
微服务
Zookeeper
dubbo
原创

zookeeper安装--->点我鸭

一. Dubbo出现的背景

在这里插入图片描述

dubbo官网-->>Dubbo官网

单体应用
所有功能都在一个应用之中,机器数量在1-10之间
垂直应用
将应用按照功能进行划分,拆分成互不相干的小应用,应用之间应该没有交互
分布式应用
“合久必分”,虽然提供的是独立的服务,但是可以被其他应用或服务所调用
SOA = Service-Oriented Architecture 面向服务的架构
通过定义接口,来提供调用方式,实际执行逻辑是被调用服务(项目B)中编写的代码
项目A AService --> 项目B BService sayHello(String msg)

早期的SOA实现方式:

1)WebService (注册、发现、调用)
此时通信的数据格式为xml,通信协议也多是http或者https

在这里插入图片描述

2)ESB = Enterprise Service Bus 企业服务总线
通过管道,将各服务进行整合,以更好的通信

在这里插入图片描述

二. 分布式系统通信方式

1.RMI

RMI = Remote Method Invocation 远程方法调用

在这里插入图片描述

客户端将要调用的方法及参数,打包为辅助对象,通过网络socket,发送给服务端辅助对象
服务端接收后,会进行解包,找出真正被调用的方法,然后将执行结果,依次再返回回去
服务端辅助对象进行打包,然后客户端辅助对象进行解包,结果返回给真正的调用者
/**
 * RMI方式的接口声明
 * 1)接口本身继承Remote
 * 2)被调用的方法也要抛出相关的异常 RemoteException
 * 因为底层需要经过网络通信,而通信是有风险的
 */
public interface HelloService extends Remote {

    String sayHello(String msg) throws RemoteException;
}
/**
 * RMI接口的实现类使用说明
 * 1)需要继承 UnicastRemoteObject远程对象类
 * 2)因为 UnicastRemoteObject 的构造函数抛出了异常所以子类也需要重写构造函数
 * 3)由于此方法的参数和返回值都需要在网络上传输所以需要可序列化
 */
public class HelloServiceImpl extends UnicastRemoteObject
        implements HelloService {

    // 序列化的版本号
    private static final long serialVersionUID = 5185759308961857565L;

    public HelloServiceImpl() throws RemoteException {
    }

    @Override
    public String sayHello(String msg) throws RemoteException {
        return "Hello, are you talking about '" + msg + "'?";
    }
}
/**
 * 暴露服务
 * 提供可被调用的端口
 */
public class RMIServer {

    public static void main(String[] args) {

        try {
            // 通过本地的注册中心
            LocateRegistry.createRegistry(9090);
            // 注册接口实现类  到具体的通讯地址下
            HelloService helloService = new HelloServiceImpl();
            Naming.bind("rmi://127.0.0.1:9090/RMIServer",helloService);
            System.out.println("rmi服务端启动成功");
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}
/**
 * 调用RMI的客户端
 */
public class RMIClient {

    public static void main(String[] args) {

        HelloService helloService = null;

        try {
            // 寻找服务端的路径  和 具体的实现逻辑
            helloService = (HelloService) Naming.lookup("rmi://127.0.0.1:9090/RMIServer");
            Object result = helloService.sayHello("rmi demo success");
            System.out.println("rmi客户端接收结果为:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
}

实现效果:

在这里插入图片描述 在这里插入图片描述

2.RPC

IPC = Inter-Process Communication 进程间通信
进程是计算机系统分配资源的最小单位,对于每个进程而言,都是资源隔离的
通信是解决,不同进程间相互访问资源的需求
LPC = Local Procedure Call 本地过程调用
RPC = Remote Procedure Call 远程过程调用
RPC真正的目的,是像调用本地方法一样去调用远程方法,而且不需要关心方法部署在哪里,这样才能够解耦服务
简单说,RPC就是从一台机器通过参数传递的方式,调用另一台机器上的方法,并得到返回结果

常用RPC框架

1) Dubbo,阿里开发,基于Spring和Netty,是当前使用最广泛的RPC框架
2) brpc,百度开发,“baidu-rpc”,支持多种协议,性能优良
3) grpc,谷歌开发,基于Netty,在人工智能领域有广泛应用,服务于tensorflow的底层通信
4) Thrift,脸书开发,已开源给apache,有一定的应用范围

三.Dubbo

1.Dubbo架构图

在这里插入图片描述

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

2.注册中心Zookeeper

最早由雅虎开发用来解决分布式系统中的一致性问题
包括配置管理、集群的扩容和缩容、分布式锁等等
1) 官网下载安装包,将tar.gz文件解压缩
2) Zookeeper也需使用本地的java环境,java_home的地址不能包含特殊字符,如中文或括号等等
3) 在本地找到一个存放zookeeper的地址,然后进入conf目录下,拷贝一份zoo_sample.cfg,命名为zoo.cfg
# The number of milliseconds of each tick
# tick是zookeeper计时的时间单位   这里表示2000ms = 2s
tickTime=2000
# The number of ticks that the initial 
# synchronization phase can take
initLimit=10
# The number of ticks that can pass between 
# sending a request and getting an acknowledgement
# 同步限制时间 (心跳时间)  单位是5tick = 10s
syncLimit=5
# the directory where the snapshot is stored.
# do not use /tmp for storage, /tmp here is just 
# example sakes.
#数据文件夹
dataDir=/root/zookeeper/data
#日志文件夹
dataLogDir=/root/zookeeper/logs
# the port at which the clients will connect
# 客户端连接zookeeper的端口号
clientPort=2181
# the maximum number of client connections.
# increase this if you need to handle more clients
#maxClientCnxns=60
#
# Be sure to read the maintenance section of the 
# administrator guide before turning on autopurge.
#
# http://zookeeper.apache.org/doc/current/zookeeperAdmin.html#sc_maintenance
#
# The number of snapshots to retain in dataDir
#autopurge.snapRetainCount=3
# Purge task interval in hours
# Set to "0" to disable auto purge feature
#autopurge.purgeInterval=1

## Metrics Providers
#
# https://prometheus.io Metrics Exporter
#metricsProvider.className=org.apache.zookeeper.metrics.prometheus.PrometheusMetricsProvider
#metricsProvider.httpPort=7000
#metricsProvider.exportJvmInfo=true

4) 启动服务并验证可以被连接
Windows下环境
进入到bin目录下执行zkServer.cmd,启动成功后,再打开新的窗口,在bin目录下执行zkCli.cmd看到命令行窗口
亦可Linux环境
测试进入到bin目录下执行zkServer.sh,启动成功后,再打开新的窗口,在bin目录下执行zkCli.sh

3.逃不了的HelloWorld

1) demo -- spring方式集成

提供一个可被调用的接口
提供方,实现接口的方法逻辑,启动应用程序,接收消费方的调用
消费方,确认要调用的接口,找到注册中心,调用提供方,获取接口的返回结果
a、启动zookeeper
b、引入相关依赖
c、声明接口及其实现类
d、创建提供方和消费方的应用程序
public interface GreetingsService {
    String sayHi(String name);
}
public class GreetingsServiceImpl implements GreetingsService {

    @Override
    public String sayHi(String name) {
        return "hi, " + name;
    }
}
//提供者
public class Application {

    //先获取zookeeper部署的ip地址
    private static String zookeeperHost = System.getProperty("zookeeper.address", "121.196.47.73");

    public static void main(String[] args) throws Exception {

        // 创建服务配置  服务对应的接口类  设置为泛型
        ServiceConfig<GreetingsService> service = new ServiceConfig<>();
        // 设置应用程序的名字
        service.setApplication(new ApplicationConfig("first-dubbo-provider"));
        // 设置注册中心  指定zookeeper的连接地址
        service.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
        // 设置提供的接口
        service.setInterface(GreetingsService.class);
        // 设置具体的实现类
        service.setRef(new GreetingsServiceImpl());
        // 设置完成  执行导出命令
        service.export();
        System.out.println("dubbo service started");
        // 让线程处于挂起的状态  一直等待接收调用端的连接
        new CountDownLatch(1).await();
    }
}
//消费者
public class Application {

    private static String zookeeperHost = System.getProperty("zookeeper.address", "121.196.47.73");

    public static void main(String[] args) {

        // 创建关联配置  要调用的接口仍然作为泛型
        ReferenceConfig<GreetingsService> reference = new ReferenceConfig<>();
        // 设置应用程序的名字
        reference.setApplication(new ApplicationConfig("first-dubbo-consumer"));
        // 设置注册中心
        reference.setRegistry(new RegistryConfig("zookeeper://" + zookeeperHost + ":2181"));
        // 设置要调用的接口
        reference.setInterface(GreetingsService.class);
        // 通过get方法  获取到远程的接口调用
        GreetingsService service = reference.get();
        // 接收到远程接口的返回结果
        String message = service.sayHi("dubbo demo");
        System.out.println(message);
    }
}

实现效果:

在这里插入图片描述

在这里插入图片描述

2) demo -- springboot方式集成

Springboot集成Dubbo参考地址
a)引入依赖(dubbo-springboot、 dubbo-zookeeper、要使用的api的依赖)
public interface DemoService {

    String sayHello(String name);
}
b)实现provider, 实现接口逻辑,增加配置参数
// 说明这个类是作为dubbo的服务被调用的
@DubboService(version = "1.0.0")
public class DemoServiceImpl implements DemoService {

    @Override
    public String sayHello(String name) {
        return "Hello," + name;
    }
}
# 配置dubbo涉及的相关参数
spring.application.name=dubbo-demo-provider
# 配置dubbo服务的扫描路径
dubbo.scan.base-packages=com.pz.provider.service

# dubbo协议相关信息
dubbo.protocol.name=dubbo
dubbo.protocol.port=2345

# dubbo注册中心地址
dubbo.registry.address=zookeeper://121.196.47.73:2181
c)实现consumer,注意配置类和主程序入口
@SpringBootApplication
public class DubboDemoConsumerApplication {

    // 对于调用端  使用的注解为DubboReference
    // 对于提供端  使用的注解为DubboService
    @DubboReference(version = "1.0.0")
    private DemoService demoService;

    public static void main(String[] args) {
        SpringApplication.run(DubboDemoConsumerApplication.class, args);
    }

    // ApplicationRunner 在程序启动后 执行代码逻辑
    @Bean
    public ApplicationRunner runner(){
        return args -> System.out.println(
                demoService.sayHello("dubbo-springboot"));
    }
}
server.port=8989
spring.application.name=dubbo-demo-consumer
dubbo.registry.address=zookeeper://121.196.47.73:2181

4.Dubbo-Admin

启动演示在此,点我鸭

操作文档

注意:

github clone项目太慢 建议使用码云从github导入仓库 然后使用码云地址clone
另外前后端项目启动需要nodejs环境 npm安装前端依赖 后端需要更改启动Zookeeper的ip+端口
建议使用前后端分离的部署方案,注意确认代码配置中的zookeeper地址是否正确

在这里插入图片描述

因为相关信息是存入到zookeeper维护的,所以本质上admin是连接zk进行查询
zookeeper中各信息的存储结构

在这里插入图片描述

  • 作者:潘震
  • 评论

    pz
    关于dubbo-admin前后端分离项目的启动演示视频我已上传至bilibili 文中有链接https://www.bilibili.com/video/BV19f4y1C7Xk
    留言