zoukankan      html  css  js  c++  java
  • dubbo入门(一)

    1、简介

    Dubbo由阿里巴巴开源,是一个分布式服务框架,致力于提供高性能和透明化的RPC(远程过程调用)远程服务调用方案,以及SOA服务治理方案。如果没有分布式的需求,Dbubbo是不需要的,其本质是远程服务调用的分布式框架,与之前的WebService不同。

    电商系统的演变过程:

    1、单一应用架构,所有的功能均部署在一起,即在一个发布包中;缺点:难以维护

    2、垂直应用架构,将系统拆分成几个子系统,每个子系统完成特定的业务;缺点:相同逻辑的代码需要不断复制,无法复用

    3、分布式应用架构,将核心业务抽取出来作为单独服务,形成稳定的服务中心,

    4、流动计算框架(SOA)。随着服务越来越多,服务之间会产生相互调用会越来越复杂,诞生了面向服务的架构体系(SOA),因此衍生出了一系列相应的技术,如对服务提供、服务调用、连接处理、通信协议、序列化方式、服务发现、服务路由、日志输出等行为进行封装的服务框架。

    Dubbo:

    1、一款分布式服务框架

    2、高性能和透明化的RPC远程服务调用方案;

    3、SOA服务治理方案;

    2、架构

    Provider:服务提供方

    Registry:服务注册与调用的注册中心

    Consumer:服务消费方

    Monitor:服务监控中心,统计服务调用时间及调用次数

    服务过程:

    0 服务容器启动、加载、运行服务提供者

    1 服务提供者在启动时向注册中心注册自己的服务

    2 服务消费方在服务启动时向注册中心订阅自己需要的服务

    3 注册中心返回服务提供者服务列表给你服务消费方,如有变更,注册中心将基于长连接推送给服务消费方

    4 服务消费方基于软负载均衡算法选择一台服务提供者进行调用,调用失败选择另外的一台

    5 服务消费者和提供者在内存中累计调用次数和时间,定时每分钟发送给监控中心

    3、Dubbo注册中心

    Dubbo提供了一下集中注册中心的类型

    1、Multicast注册中心 多播

    2、Zookeeper注册中心,使用zookeeper

    3、Redis注册中心,使用Redis

    4、Simple注册中心,

    4、Dbubbo优缺点

    4.1、优点

    1、透明化的远程方法调用

    - 像调用本地方法一样调用远程方法;只需简单配置,没有任何API侵入。/2、软负载均衡及容错机制

    可在内网替代nginx lvs等硬件负载均衡器。

    3、服务注册中心自动注册 & 配置管理

    -不需要写死服务提供者地址,注册中心基于接口名自动查询提供者ip。

    使用类似zookeeper等分布式协调服务作为服务注册中心,可以将绝大部分项目配置移入zookeeper集群。

    4、服务接口监控与治理

    -Dubbo-admin与Dubbo-monitor提供了完善的服务接口管理与监控功能,针对不同应用的不同接口,可以进行 多版本,多协议,多注册中心管理。

    4.2、缺点

    仅支持JAVA语言

    5、Demo

    5.1、简介

    注册中心使用zookeeper,安装使用可参见下面。

    项目使用maven的构建方式,提供服务提供者和服务消费者,另外还需一个服务接口,共新建三个maven项目:dubbo-api、dubbo-provider、dubbo-consumer;

    dubbo-api:服务接口,需单独打包,供服务提供者和消费者使用;

    dubbo-provider:服务提供者,依赖dubbo-api,实现其接口;

    dubbo-consumer:服务消费者,依赖dubbo-api,调用服务提供者的服务;

    Dubbo采用全Spring配置方式,透明化接入应用,对应用没有任何API侵入,只需用spring加载Dubbo配置即可,基于spring的Schema扩展进行加载。

    demo需要用到spring、zookeeper、zkclient等jar包。使用spring-4.3.16.RELEASE、zookeeper.3.4.10、dubbo.2.5.2、zkclient.0.10

    5.2zookeeper安装

    详见《zookeeper安装》

    5.3dubbo-api

    新建maven项目,此项目中提供一个服务接口:UserService,另为了方便接口间数据的交互可使用javabean,这里提供一个User类,由于是网络间的传输,需实现Serializable。

    UserService

    package cn.com.dubbo_api.service;
    
    import java.util.List;
    
    import cn.com.dubbo_api.entity.User;
    
    /**
     * * 
    *<p>Title: UserService</p>
    * <p>Description: 用户服务API</p>
    * <p>Company: </p>
    * @author Administrator
    * @date 2018年5月24日 上午10:30:59
     */
    public interface UserService {
    
        //批量新增
        public int addUsers(List<User> users);
        //查询所有
        public List<User> findUsers();
        //删除
        public int deleteUser(User user);
        //单个新增
        public int addUser(User user);
        //更新
        public int updateUser(User user);
        //查询单个
        public User findUser(User user);
    }

    User

    package cn.com.dubbo_api.entity;
    
    import java.io.Serializable;
    
    /**
     * * 
    *<p>Title: User</p>
    * <p>Description:用户实体类 </p>
    * <p>Company: </p>
    * @author Administrator
    * @date 2018年5月24日 上午10:30:43
     */
    public class User implements Serializable{
    
        private Long id;
        private String name;
        private String address;
        private Integer age;
        public Long getId() {
            return id;
        }
        public void setId(Long id) {
            this.id = id;
        }
        public String getName() {
            return name;
        }
        public void setName(String name) {
            this.name = name;
        }
        public String getAddress() {
            return address;
        }
        public void setAddress(String address) {
            this.address = address;
        }
        public Integer getAge() {
            return age;
        }
        public void setAge(Integer age) {
            this.age = age;
        }
        public User() {
            // TODO Auto-generated constructor stub
        }
        public User(Long id,String name,String address,Integer age) {
            // TODO Auto-generated constructor stub
            this.id=id;
            this.name=name;
            this.address=address;
            this.age=age;
        }
        @Override
        public String toString() {
            return "User [id=" + id + ", name=" + name + ", address=" + address + ", age=" + age + "]";
        }
        
    }

    5.4dubbo-provider

    新建maven项目,由于此为服务提供者故需引入spring、zookeeper等的jar包,还需引入dubbo-api,具体实现类为;

    UserServiceImpl

    package cn.com.dubbo_provider.serviceImpl;
    
    import java.util.ArrayList;
    import java.util.HashMap;
    import java.util.List;
    import java.util.Map;
    import java.util.Set;
    
    import cn.com.dubbo_api.entity.User;
    import cn.com.dubbo_api.service.UserService;
    
    public class UserServiceImpl implements UserService {
    
        private Map<Long,User> userMap=new HashMap<Long,User>();
        
        public int addUsers(List<User> users) {
            // TODO Auto-generated method stub
            int num=0;
            if(users!=null&&users.size()>0) {
                for (User user : users) {
                    userMap.put(user.getId(), user);
                }
                num=users.size();
            }
            return num;
        }
    
        public List<User> findUsers() {
            // TODO Auto-generated method stub
            if(isNull(userMap)) {
                return null;
            }
            List<User> users=new ArrayList<User>();
            Set<Long> keySet=userMap.keySet();
            for (Long id : keySet) {
                users.add(userMap.get(id));
            }
            return users;
        }
    
        public int deleteUser(User user) {
            // TODO Auto-generated method stub
            if(isNull(userMap)) {
                return 0;
            }
            User delUser=userMap.remove(user.getId());
            if(delUser!=null) {
                return 1;
            }
            return 0;
        }
    
        public int addUser(User user) {
            // TODO Auto-generated method stub
            userMap.put(user.getId(), user);
            return 1;
        }
    
        public int updateUser(User user) {
            // TODO Auto-generated method stub
            if(userMap.containsKey(user.getId())) {
                userMap.put(user.getId(), user);
            }
            return 1;
        }
    
        public User findUser(User user) {
            // TODO Auto-generated method stub
            return userMap.get(user.getId());
        }
    
        //判断Map是为空
        public boolean isNull(Map map) {
            boolean b=false;
            if(map.isEmpty()) {
                b= true;
            }
            return b;
        }
    }

    Spring的配置:spring-privider.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: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">
    
    <!-- 定义服务的实现接口 -->
    <bean id="userService" class="cn.com.dubbo_provider.serviceImpl.UserServiceImpl"></bean>
     <!--定义了提供方应用信息,用于计算依赖关系;在 dubbo-admin 或 dubbo-monitor 会显示这个名字,方便辨识-->
        <dubbo:application name="demotest-provider" owner="programmer" organization="dubbox"/>
        <!--使用 zookeeper 注册中心暴露服务,注意要先开启 zookeeper-->
        <dubbo:registry address="zookeeper://192.168.199.128:2181"/>
        <!-- 用dubbo协议在20880端口暴露服务 -->
        <dubbo:protocol name="dubbo" port="20880" />
        <!--使用 dubbo 协议实现定义好的 api.PermissionService 接口-->
        <dubbo:service interface="cn.com.dubbo_api.service.UserService" ref="userService" protocol="dubbo" />
    </beans>

    服务启动类:

    package cn.com.dubbo_provider;
    
    import java.io.IOException;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    /**
     * Hello world!
     *
     */
    public class App 
    {
        public static void main( String[] args ) throws IOException
        {
            System.out.println( "Hello World!" );
            
            ClassPathXmlApplicationContext cac=new ClassPathXmlApplicationContext("spring-provider.xml");
            cac.start();
            System.out.println("服务已经启动...");
            System.in.read();
        }
    }

    5.5dubbo-consumer

    新建maven项目,引入spring、zookeeper、dubbo-api的依赖。

    由于是服务消费者则直接测试即可,下面看spring配置文件,

    spring的配置文件:spring-consumer.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: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:application name="demotest-consumer" owner="programmer" organization="dubbox"/>
        <!--向 zookeeper 订阅 provider 的地址,由 zookeeper 定时推送-->
        <dubbo:registry address="zookeeper://192.168.199.128:2181"/>
        <!--使用 dubbo 协议调用定义好的 api.PermissionService 接口-->
        <dubbo:reference id="permissionService" interface="cn.com.dubbo_api.service.UserService"/>
    </beans>

    测试类:

    package cn.com.dubbo_consumer;
    
    import java.util.List;
    
    import org.springframework.context.support.ClassPathXmlApplicationContext;
    
    import cn.com.dubbo_api.entity.User;
    import cn.com.dubbo_api.service.UserService;
    
    /**
     * Hello world!
     *
     */
    public class App 
    {
        public static void main( String[] args )
        {
            System.out.println( "Hello consumer!" );
            
            ClassPathXmlApplicationContext cac=new ClassPathXmlApplicationContext("spring-consumer.xml");
            cac.start();
            
            UserService us=cac.getBean(UserService.class);
            
         
            User u=new User(1l,"tom1","uc",22);
            int k=us.addUser(u);
            System.out.println("k:"+k);
            
            List<User> list=us.findUsers();
            System.out.println(list.size());
            for (User user : list) {
                System.out.println("user:"+user.toString());
            }
            System.out.println(us.findUser(new User(3l,null,null,0)));
        }
    }

    以上的三个项目,dubbo-api作为服务接口,只提供接口的定义,作为服务提供者和服务消费者的接口,需单独打包。dubbo-provider和dubbo-consumer作为服务提供者和服务消费者分别打包、运行。

    感谢,1046386199可交流!

  • 相关阅读:
    Redis:特殊数据类型,hyperloglog(基数),bitmap(位存储)
    Redis:特殊类型geospatial(地理位置类型,纬经度)
    Redis:zset常用指令
    Redis:hash常用指令
    Redis:set集合常用常用指令
    Pytorch学习-数据操作
    天池Python训练营笔记—Python基础入门:从变量到异常处理
    Python基础语法快速复习-面对对象编程
    Python基础语法快速复习-函数式编程
    Python基础语法快速复习-高级特性
  • 原文地址:https://www.cnblogs.com/teach/p/9084448.html
Copyright © 2011-2022 走看看