Dubbo学习笔记

Dubbo简介

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

1、用途

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

2、架构

Dubbo学习笔记_第1张图片

节点介绍

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

Dubbo学习笔记_第2张图片

 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学习笔记_第3张图片

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

3、Dubbo的简单实现

1、创建服务提供方:

结构如下:

Dubbo学习笔记_第4张图片

provider代码:



    
    
    
    
    
    
    
    
    
    

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 getPermissions(Long id);
    List 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 getPermissions(Long id) {
        List demo = new ArrayList();
        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 getPersion(String name, String address, Integer age, String gender) {
        List 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 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() {
                @Override
                public GenericService call() throws Exception {
                    ReferenceConfig 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 -- 系统学习 笔记 -- 入门

你可能感兴趣的:(分布式)