Dubbo学习笔记

本文介绍了Dubbo作为分布式服务框架的基本概念、用途、架构及其优势。详细讲述了Dubbo与Zookeeper的配合使用,包括Zookeeper的安装配置,以及如何安装和配置dubbo-admin管理页面。同时,文中还给出了服务提供方和消费方的简单实现示例。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Dubbo简介

互联网的发展,网站应用的规模不断扩大,常规的垂直应用架构已无法应对,分布式服务架构以及流动计算架构势在必行,Dubbo是一个分布式服务框架,在这种情况下诞生的。现在核心业务抽取出来,作为独立的服务。

1、用途

  1. dubbo采用统一的注册中心,动态的注册和订阅服务。消费者在请求提供方数据时,实现软负载均衡。
  2. 监控中心负责统计各服务调用次数,调用时间等,可以用于容量规划的依据。

2、架构

节点介绍

1、Provider:服务提供方

2、Register:服务的注册和订阅的注册中心

3、Consumer:服务的消费者

4、Monitor:监控中心,用于统计服务的调用次调和调用时间。(可以没有)

5、Container:服务运行容器。

服务调用过程

服务运行容器加载启动服务提供者-->服务者在注册中心注册自己要对外提供的服务-->消费者向注册中心订阅需要的服务-->注册中心通知消费者提供者地址列表-->消费者基于软负载均衡,选择一台提供者进行调用。若调用失败,换另一台再次调用。--> 监控中心统计在内存中累计调用次数和调用时间。

架构好处

1、注册中心不转发请求,压力较小。服务提供者和消费者只在启动时与注册中心交互

2、监控中心统计在内存中累计调用次数和调用时间。

3、注册中心使用集群,出现宕机可以即时切换。注册中心数据库宕机不影响服务的订阅,只是不能进行注册

4、可以有多个服务提供方提供服务。

2、Dubbo与Zookeeper配合使用

1、linux安装zookeeper

Zookeeper一个分布式的服务框架,能做到集群管理数据 ,这里能很好的作为Dubbo服务的注册中心

  • 下载zookeeper-3.4.10.tar.gz
  • 解压压缩包:tar -xvf zookeeper-3.4.10.tar.gz
  • 进入zookeeper下的conf目录,复制zoo_sample.cfg一份副本,并改名为zoo.cfg
  • 修改zoo.cfg

 clientPort:监听客户端连接的端口。

 tickTime:基本事件单元,以毫秒为单位。它用来控制心跳和超时,默认情况下最小的会话超时时间为两倍的 tickTime。

 maxClientCnxns:限制连接到 ZooKeeper 的客户端的数量等

 dataDir和dataLogDir:分别用于snapshot和事务日志的输出

2、安装dubbo-admin管理页面

  • 下载dubbo-admin-2.5.4.war 重命名为ROOT.war,用此ROOT.war扔到Tomcat的webapp目录下的
  • 启动tomcat后会自动解压war包,进入ROOT/WEB-INF/目录下,修改dubbo.properties文件


注:dubbo.properties默认提供了两组账号密码:root admin;guest guest。

3、Dubbo的简单实现

1、创建服务提供方:

结构如下:


provider代码:

<?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:dubbo="http://code.alibabatech.com/schema/dubbo"
       xsi:schemaLocation="http://www.springframework.org/schema/beans
       http://www.springframework.org/schema/beans/spring-beans.xsd
       http://code.alibabatech.com/schema/dubbo
       http://code.alibabatech.com/schema/dubbo/dubbo.xsd">
    <!--定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
    <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>
    <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
    <dubbo:registry address="zookeeper://192.168.60.131:2181"/>
    <!-- 用dubbo协议在20880端口暴露服务 -->
    <dubbo:protocol name="dubbo" port="20880" />
    <!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
    <dubbo:service interface="com.alibaba.dubbo.demo.impl.DemoService" timeout="30000"
                   ref="demoService" protocol="dubbo" />
    <!--具体实现该接口的 bean-->
    <bean id="demoService" class="com.alibaba.dubbo.demo.impl.DemoServiceImpl"/>
</beans>

DemoService和DemoServiceImpl定义了两个对外提供的方法

package com.alibaba.dubbo.demo.impl;

import com.alibaba.dubbo.demo.Persion;
import java.util.List;

/**
 * Created by yi on 2018/2/28.
 */
public interface DemoService {

    List<String> getPermissions(Long id);
    List<Persion> getPersion(String name, String addr, Integer age, String gender);
}

package com.alibaba.dubbo.demo.impl;

import com.alibaba.dubbo.demo.Persion;
import java.util.ArrayList;
import java.util.List;

public class DemoServiceImpl implements DemoService {
    public List<String> getPermissions(Long id) {
        List<String> demo = new ArrayList<String>();
        demo.add(String.format("Permission_%d", id - 1));
        demo.add(String.format("Permission_%d", id));
        demo.add(String.format("Permission_%d", id + 1));
        return demo;
    }

    @Override
    public List<Persion> getPersion(String name, String address, Integer age, String gender) {
        List<Persion> persions = new ArrayList<>();
        Persion persion = null;
        for (int i = 0; i < 10; i++) {
            persion = new Persion();
            persion.setName(name + i);
            persion.setAddr(address + i);
            persion.setAge(age + i);
            persion.setGender(gender+i);
            persions.add(persion);
        }
        return persions;
    }
}

persion对象

package com.alibaba.dubbo.demo;

/**
 * Created by yi on 2018/2/24.
 */
public class Persion {

    private String name;

    private String addr;

    private Integer age;

    private String gender;

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getAddr() {
        return addr;
    }

    public void setAddr(String addr) {
        this.addr = addr;
    }

    public Integer getAge() {
        return age;
    }

    public void setAge(Integer age) {
        this.age = age;
    }

    public String getGender() {
        return gender;
    }

    public void setGender(String gender) {
        this.gender = gender;
    }
}

Provider:注册服务并持续提供服务

package com.alibaba.dubbo.demo.impl;

import org.springframework.context.support.ClassPathXmlApplicationContext;
import java.io.IOException;

public class Provider {
    public static void main(String[] args) throws IOException {
        ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("provider.xml");
        System.out.println(context.getDisplayName() + ": here");
        context.start();
        System.out.println("服务已经启动...");
        System.in.read();
    }
}

消费方代码:使用GenericService实现泛型接收返回值。使用java代码配置zookeeper。

package com.alibaba.dubbo.consumer;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ReferenceConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.rpc.service.GenericService;
import com.google.common.cache.Cache;
import com.google.common.cache.CacheBuilder;
import java.util.concurrent.Callable;
import java.util.concurrent.TimeUnit;

public class Consumer {
    //缓存持续时间
    private static Long cacheDubTimes = 1000 * 60 *12L;
    //应用信息(提供方名称)
    private static ApplicationConfig APPLICATION = null;
    //zookeeper 注册中心url
    private static RegistryConfig REGISTRY = null;
    //dubbo实体类
    private static DubConfig dubConfig = null;

    private static ConsumerConfig CONSUMER = null;
    
    //缓存保存(接口名称,泛型service)
    private static Cache<String, GenericService> servicesCache= CacheBuilder.newBuilder().expireAfterAccess(
            cacheDubTimes, TimeUnit.SECONDS).maximumSize(200).build();
    /**
     *
     * @param interfaceName 接口名称
     * @return
     */
    private static ReferenceConfig createReferenceConfig(String interfaceName) {

        //接口引用
        ReferenceConfig referenceConfig = new ReferenceConfig<>();
        referenceConfig.setApplication(getApplicationConfig());
        referenceConfig.setRegistry(getRegistryConfig());
        referenceConfig.setConsumer(getConsumerConfig());
        referenceConfig.setInterface(interfaceName);
        referenceConfig.setGeneric(true);

        return referenceConfig;
    }

    private static ApplicationConfig getApplicationConfig() {
        if (APPLICATION != null) {
            return APPLICATION;
        }
        APPLICATION = new ApplicationConfig(dubConfig.getDubApplicationName());
        return APPLICATION;
    }

    private static RegistryConfig getRegistryConfig(){
        if (REGISTRY != null) {
            return REGISTRY;
        }
        REGISTRY = new RegistryConfig(String.join("", "zookeeper://", dubConfig.getDubZookeeperUrl()));
        return REGISTRY;
    }

    private static ConsumerConfig getConsumerConfig(){
        if (CONSUMER != null) {
            return CONSUMER;
        }
        CONSUMER = new ConsumerConfig();
        CONSUMER.setTimeout(dubConfig.getDubTimeout());
        CONSUMER.setRetries(0);
        return CONSUMER;
    }

    private static GenericService getServiceByCache(String interfaceName) {
        StringBuilder serviceKey = new StringBuilder(String.join("", interfaceName));

        GenericService service = null;

        try {
            service = servicesCache.get(serviceKey.toString(), new Callable<GenericService>() {
                @Override
                public GenericService call() throws Exception {
                    ReferenceConfig<GenericService> referenceConfig = createReferenceConfig(interfaceName);
                    GenericService genericService = referenceConfig.get();
                    servicesCache.put(serviceKey.toString(), genericService);
                    return genericService;
                }
            });

        } catch (java.util.concurrent.ExecutionException e) {
            e.printStackTrace();
        }
        if (service != null) {
            return service;
        }
        servicesCache.put(serviceKey.toString(), null);
        return service;

    }
    
    public static void main(String[] args) {
        if (dubConfig == null) {
            dubConfig = new DubConfig();
            dubConfig.setDubTimeout(3000);
            dubConfig.setDubApplicationName("demotest-consumer");
            dubConfig.setDubZookeeperUrl("192.168.60.131:2181");
        }

        GenericService genericService = getServiceByCache("com.alibaba.dubbo.demo.impl.DemoService");
        String[] parameterTypes = new String[]{String.class.getName(), String.class.getName(), Integer.class.getName(), String.class.getName()};
        Object[] dubArgs = new Object[]{"小明", "北京", "11", "男"};
        Object obj= genericService.
                $invoke("getPersion", parameterTypes, dubArgs);
        System.out.println("---------  ----------  ------------  ---------");
        System.out.println(obj);
    }
}

部分内容引用:

Dubbo分布式服务框架的简单理解      Dubbo -- 系统学习 笔记 -- 入门

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值