zoukankan      html  css  js  c++  java
  • Dubbo

    Apache Dubbo是一个高可用的,基于java的开源RPC框架

    不仅包含RPC访问功能,还包含服务治理功能

    由阿里巴巴建立,最后由apache维护至今,所以我们选择由apache维护的dubbo

    官方地址:https://mvnrepository.com/artifact/org.apache.dubbo/dubbo

    常用版本2.7.3

    Dubbo架构

    Dubbo支持的协议

    Dubbo协议(官方推荐)

    采用NIO复用单一长连接,使用线程池并发处理请求,减少握手和加大并发效率

    大文件上传时,可能出现问题(不适用Dubbo文件上传)

    RMI协议(Remote Method Invocation)

    优点:JDK自带的能力

    缺点:偶尔连接失败

    Hessian协议

    优点:可以与原生Hessian互操作,基于HTTP协议

    缺点:需hessian.jar支持,http短连接的开销大

    Dubbo支持的注册中心

    Zookeeper(官方推荐)

    优点:支持分布式,周边产品

    缺点:受限于Zookeeper软件的稳定性,Zookeeper专门分布式辅助软件,稳定较优

    Multicast

    优点:去中心化,不需要单独安装

    缺点:Provider和Consumer和Registry不能跨机房(只能在局域网内使用)

    Redis

    优点:支持集群,性能高

    缺点:要求服务器时间同步,否则可能出现集群失败问题

    Simple

    优点:标准RPC服务,没有兼容问题

    缺点:不支持集群

    第一个Dubbo的Provider

    Dubbo目录结构

    创建父工程,添加依赖

    <parent>
        <group>org.springframework.boot</group>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.1.10.RELEASE</version>
    </parent>
    <dependencyManagement>
    <dependencies>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter</artifactId>
        <version>2.4.2</version>
    </dependency>
    <dependency>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-web</artifactId>
        <version>2.1.10 RELEASE</version>
    </dependency>
    <dependency>
        <groupId>org.apache.dubbo</groupId>
        <artifactId>dubbo-spring-boot-starter</artifactId>
        <version>2.7.3</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-recipes</artifactId>
        <version>4.2.0</version>
    </dependency>
    <dependency>
        <groupId>org.apache.curator</groupId>
        <artifactId>curator-framework</artifactId>
        <version>4.2.0</version>
    </dependency>
    </dependencyManagement>

    DubboService接口

    public interface DubboService{
        public String service(String param);
    }

    接口实现

    @Service
    public class DubboServiceImpl implements DubboService{
    
        @Reference
        private dubboService DubboService;
    
        @Override
        public String service(String param){
            return DubboService.service("dubbo");
        }
    }

    启动类

    @SpringBootApplication
    @EnableDubbo
    public class ProviderApplication{
        public static void main(String[] args){
            SpringApplication.run(ProviderApplication.class, args);    
        }
    }

    控制器

    public class DubboController{
        @Autowired
        private DubboService dubboService;
        
        @RequestMapping("/dubboservice")
        @RequestBody
        public String service(){
            return dubboService.service();
        }
    }

    provider中的application.yml

    dubbo:
        application:
            name: dubbo-provider
            registry:
              address: zookeeper://192.168.0.1:2181
        protocol:
          port: 20884

    consumer中的application.yml

    dubbo:
        application:
            name: dubbo-consumer
            registry:
              address: zookeeper://192.168.0.1:2181
        protocol:
          port: 20884

    Admin管理界面搭建

    负载均衡

    集群:一个内容,部署多次,形成的整体称为集群,每个个体应该部署到不同的服务器

    伪集群:集群中内容部署到同一台服务器上,通过不同端口区分不同个体

    负载均衡是在集群前提下,当访问整个集群时,集群中每个节点都被访问次数或频率的规则

    Dubbo内置了四个负载均衡策略,默认为Random

    内置策略

    • Random,随机,随机访问集群中结点,访问概率和权重有关
    • RoundRobin,轮询,访问频率和权重有关;权重,占有比例,集群中每个项目部署的服务器性能可能不同,性能好的权重高
    • LeastActive,活跃数相同的随机,不同的活跃数高的放前面
    • ConsistentHash,一致性Hash,相同参数请求总是发到一个提供者

    Provider集群

    新建四个启动类

    每次启动启动类修改配置文件dubbo.protocal.port

    设置负载均衡

    调用的服务采用负载均衡

    @Reference(loadbalance = "roundrobin")
    private DubboService dubboService;

    当前拂去采用的负载均衡算法

    @Service(loadbalance = "random")
    public class DubboServiceImpl implements DubboService{}

    设置权重

    @Service(weight = 4)

    配置文件

    dubbo:
        application:
            name: dubbo-provider
        registry:
            address: zookeeper://192.168.32.128:2181
        protocol:
            port: 20884

    结构图

    pojo.Dept.java

    public class Dept implements Serializable{
        private Integer id;
        private String name;
        // getter setter
    }

    pojo.Emp.java

    public class Emp implements Serializable{
        private Integer id;
        private String name;
        private Stgring phote;
        private Integer did;
        // getter setter
    }

    持久层myBatis

    application-mybatis.yml

    spring:
        datasource:
            driver-class-name: com.mysql.jdbc.Driver
            url: jdbc:mysql://localhost:3306/test
            username: root
            password: root
    mybatis:
        mapper-locations: classpath:mybatis/*.xml
        type-aliases-package: com.test.pojo

    mapper.DeptMapper

    mapper.EmpMapper

    provider启动类

    @SpringBootApplication
    @EnableDubbo
    @MapperScan(com.test.mapper)
    public class ProviderApplication{
        public static void main(String[] args){
            SpringApplication.run(ProviderApplication.class, args);
        }
    }

    provider的applicaton.yml

    dubbo:
        application:
            name: dubbo-provider
        registry:
            address: zookeeper://192.168.0.1:2181
    # 加载其它配置文件, 加载其它的application-*.yml文件
    # 多个名称之间用 "," 分隔
    spring: 
        profiles:
            active: mybatis

    dept子项目的创建

    DeptMapper.xml

    <mapper namespace="com.test.mapper.DeptMapper">
        <select id="findAll" resultType="com.test.pojo.Dept">
            select id, name from dept;
        </select>
    </mapper>

    DeptDubboService

    public interface DeptDubboService{
        public List<Dept> findAllDept();
    
    }

    DeptMapper

    public interface DeptMapper{
        public List<Dept> findAll();
    }

    DeptDubboServiceImpl

    // 选择Dubbo注解
    @Service
    public class DeptDuboServiceImpl implements DeptDubboService(){
        @Autowired
        private DeptMapper deptMapper;
    
        @Override
        public List<Dept> findAllDept(){
            return deptMapper.findAll();
        }
    }

    DeptService

    public interface DeptService{
        public List<Dept> findAll();
        public List<Emp> findEmpByDeptId(Integer did);
    }

    DeptServiceImpl

    public class DeptServiceImpl implements DeptService{
    
        @Reference
        private DeptDubboService deptDubboService;
        
        @Override
        public List<Dept> findAll(){
            return null;
        }
    }

    DeptController

    @Controller
    public class DeptController{
        @Autowired
        private DeptService deptService;
        @GetMapping("/dept")
        public String showDept(Model model){
            model.setAttribute("list", deptService.findAll());
            return "dept";
        }
    }

    启动类

    @SpringBootApplication
    @EnableDubbo
    @MapperScan("com.test.mapper")
    public class ProviderApplication{
        public static void main(String[] args){
            SpringApplication.run(ProviderApplication.class, args);
        }
    }

    emp下的application.yml

    dubbo:
        application:
            name: dubbo-emp-consumer
        registry:
            address: zookeeper://192.168.0.1
    server:
        port: 8081

    EmpApplication

    @SpringBootApplication
    @EnableDubbo
    public class EmpApplication{
        public static void main(String[] args){
            SpringApplication.run(EmpApplication.class, args);
        }
    }

    EmpDubboService

    public interface EmpDubboService{
        public int insertEmp(Emp emp);    
        public List<Emp> findEmpByDeptId(Integer did);
    }

    EmpDubboServiceImpl

    public class EmpDubboServiceImpl implements EmpDubboService{
        @Autowired
        private EmpMapper empMapper;
    
        @Override
        public int insertEmp(Emp emp){
            return empMapper.insertEmp(emp);
        }
    }

    EmpMapper.xml

    <mapper namespace="com.test.mapper.EmpMapper" >
        <insert id="insertEmp" parameterType="com.test.pojo.Emp">
            insert into emp(name, photo, did) values(#{name}, #{photo}, #{did})
        </insert>
    <select id="findEmpByDeptId" parameterType="int" resultType="com.test.pojo.Emp">
    select id, name, photo from emp where did = #(did)
    </select> </mapper>

    EmpService

    public interface EmpService{
        public List<Dept> showAll();
        public int insert(Emp emp, MultipartFile file);    
    }

    EmpDubboServiceImpl

    public class EmpDubboServiceImpl implements EmpService{
        // Dubbo 的 Reference
        @Reference
        private DeptDubboService deptDubboService;
        @Reference
        private EmpDubboService empDubboService;
        @Override
        public List<Dept> showAll(){
            return deptDubboService.findAllDept();
        }
        @Override
        public int insert(Emp emp, MultipartFile file){    
            try{
                // 通过spring容器获取HttpServletRequeest对象
                HttpServletRequeest request = ((ServletRequestAttributes)RequestContextHolder.getRequestAttributes()).getRequest();
                // 通过HttpServletRequest对象获取图片上传的路径
                String path = request.getServletContext().getRealPath("/img");
                System.out.println("path == " + path);
    
                // 为上传到服务器中的图片的名称不重复, 编写随机数
                long currentTimeMills = System.currentTimeMillis();
                Random random = new Random();
                String fileName = currentTimeMills + "" + random.nextInt(1000);
                String oldName = file.getOriginalFilename();
                fileName += oldName.substring(oldName.lastIndexOf("."));
    
                File pathFile = new File(path);
                // 第一次上传图片, 检查目录是否存在, 如果不存在, 创建响应目录
                if(!pathFile.exist()){
                    pathFile.mkdirs();
                }
                // 图片上传        
                file.transferTo(new File(path, fileName));
                // 封装emp对象, 把图片路径封装到emp对象中
                emp.setPhoto("http://localhost:8081/img/" + fileName);
                return empDubboService.insertEmp(emp);
            }catch(IOException e){
                e.printStackTrace();
            }        
            return 0;
        }
    }

    EmpController

    public class EmpController{
        @Autowired
        private EmpService empService;
    
        @GetMapping("/empadd")
        public String empAdd(Model model){
            model.addAttribute("list", empService.showAll());
    
            return "emp-add";
        }
    
        @PostMapping("/add")
        public String add(Emp emp, MultipartFile file){
            empService.insert(emp, file);
            return "emp-add";
        }
    }

    DeptController

    @Controller
    public class DeptController{
        @Autowired
        private DeptService deptService;
        @GetMapping("/dept")
        public String showDept(Model model){
            model.addAttribute("list", deptService.findAll());    
            return "dept";    
        }
    
        @GetMapping("/showEmp")
        public String showEmp(Integer did, Model model){
            model.addAttribute("list", deptService.findEmpByDeptId(did));    
            return "showEmp";    
        }
    }
    论读书
    睁开眼,书在面前
    闭上眼,书在心里
  • 相关阅读:
    Python 字符串处理大全.
    图形化翻译助手
    爬虫详解
    Python 模块.
    定制序列
    Python 的property的实现 .
    Python的魔法方法 .
    通过类的装饰器以及各种单例模式(修复版本)。
    是时候写一下Python装饰器了。
    %E2%80%8C的字符串问题,卡住三个小时。
  • 原文地址:https://www.cnblogs.com/YC-L/p/14360552.html
Copyright © 2011-2022 走看看