专注于 JetBrains IDEA 全家桶,永久激活,教程
持续更新 PyCharm,IDEA,WebStorm,PhpStorm,DataGrip,RubyMine,CLion,AppCode 永久激活教程

ZooKeeper与Dubbo注解配置

今天来聊一聊分布式框架。介绍一下ZooKeeper与Dubbo。

下载链接:ZooKeeper

  • 二进制文件,下载这个 apache-zookeeper-3.5.5-bin.tar.gz
  • 源码,要研究源码,可以下这个 apache-zookeeper-3.5.5.tar.gz

Mac下使用ZooKeeper(单点模式)

  • 修改zookeeper/conf下的zoo_sample.cfg文件,将zoo_sample.cfg重命名为zoo.cfg
  • cd到当前目录 终端下执行 zkServer start
  • 查看状态 zkServer status
  • 连接到zk,zkCli -server localhost

89_1.png

下面是zk中的一些命令,日常工作基本不会用到。有查看节点,新增节点,修改节点,删除节点。

89_2.png

89_3.png

ZooKeeper中的角色

角色 描述
领导者(leader) 负责投票的发起和决议,更新系统状态
学习者(learner)-跟随者(follower) 接收客户端请求并向客户端返回结果,在选主过程中参与投票
学习者(learner)-观察者(observer) 可以接收客户端连接,将请求转发给leader节点,但是不参与投票过程,
只同步leader状态,observer是为了扩展系统,提高读取速度
客户端(client) 请求发起方

Dubbo

节点角色说明

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

调用关系说明

  • 服务容器负责启动,加载,运行服务提供者。
  • 服务提供者在启动时,向注册中心注册自己提供的服务。
  • 服务消费者在启动时,向注册中心订阅自己所需的服务。
  • 注册中心返回服务提供者地址列表给消费者,如果有变更,注册中心将基于长连接推送变更数据给消费者。
  • 服务消费者,从提供者地址列表中,基于软负载均衡算法,选一台提供者进行调用,如果调用失败,再选另一台调用。
  • 服务消费者和提供者,在内存中累计调用次数和调用时间,定时每分钟发送一次统计数据到监控中心。

现在SpringBoot都更新到2.0版本了,就用注解配置吧。不用xml了…

嗯,简单一点,不用数据库了

89_4.png

89_5.png

  • 配置好Swagger,全局异常拦截器

    89_6.png

  • 添加api模块

    89_7.png

  • 最后的结构

    89_8.png

gradle:build.gradle

allprojects {
    apply plugin: 'java'
    apply plugin: 'idea'
    apply plugin: 'maven'
    apply plugin: 'eclipse'
    apply plugin: 'org.springframework.boot'
    apply plugin: 'io.spring.dependency-management'
    apply plugin: "io.franzbecker.gradle-lombok"

    group = 'com.ler.dubbo'
    version = '1.0.0-SNAPSHOT'
    sourceCompatibility = '1.8'

    jar.enabled = true

    configurations {
        developmentOnly
        runtimeClasspath {
            extendsFrom developmentOnly
        }
        compileOnly {
            extendsFrom annotationProcessor
        }
    }

    repositories {
        mavenCentral()
    }

    dependencies {
        implementation 'org.springframework.boot:spring-boot-starter-web'
        compileOnly 'org.projectlombok:lombok'
        annotationProcessor 'org.projectlombok:lombok'
        testImplementation 'org.springframework.boot:spring-boot-starter-test'

        //dubbo zk
        compile group: 'com.alibaba', name: 'dubbo', version: '2.6.1'
        compile(group: 'com.101tec', name: 'zkclient', version: '0.10') {
            exclude group: 'log4j', module: 'log4j'
            exclude group: 'org.slf4j', module: 'slf4j-api'
            exclude group: 'org.slf4j', module: 'slf4j-log4j12'
        }
        compile('org.apache.curator:curator-recipes:4.0.1') {
            exclude group: 'org.apache.zookeeper', module: 'zookeeper'
        }
    }
}

buildscript {
    ext {
        springBootVersion = '2.0.2.RELEASE'
    }
    repositories {
        maven {
            url "https://plugins.gradle.org/m2/"
        }
    }
    dependencies {
        classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}")
        classpath "io.franzbecker:gradle-lombok:1.14"
    }
}

dependencies {

    compile project(":api")

    implementation 'org.springframework.boot:spring-boot-starter-web'
    compileOnly 'org.projectlombok:lombok'
    annotationProcessor 'org.projectlombok:lombok'
    testImplementation 'org.springframework.boot:spring-boot-starter-test'
    testImplementation 'org.springframework.restdocs:spring-restdocs-mockmvc'

    compile group: 'com.alibaba', name: 'fastjson', version: '1.2.55'
    compile group: 'org.apache.commons', name: 'commons-lang3', version: '3.8.1'

    compile group: 'io.springfox', name: 'springfox-swagger2', version: '2.9.2'
    compile group: 'io.springfox', name: 'springfox-swagger-ui', version: '2.9.2'

}

因为没有数据库,所以application.properties配置简单了很多。 为了防止冲突,只有一个端口配置

server.port=8081

swagger 配置

package com.ler.dubbo.demo.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurer;
import springfox.documentation.builders.ApiInfoBuilder;
import springfox.documentation.builders.RequestHandlerSelectors;
import springfox.documentation.service.ApiInfo;
import springfox.documentation.spi.DocumentationType;
import springfox.documentation.spring.web.plugins.Docket;
import springfox.documentation.swagger2.annotations.EnableSwagger2;

/**
 * @author lww
 */
@Configuration
@EnableSwagger2
public class SwaggerConfig implements WebMvcConfigurer {

    @Bean
    public Docket api() {
        return new Docket(DocumentationType.SWAGGER_2)
                .forCodeGeneration(true)
                .select()
                .apis(RequestHandlerSelectors.basePackage("com.ler.dubbo.demo.controller"))
                .build()
                .apiInfo(apiInfo());
    }

    private ApiInfo apiInfo() {
        return new ApiInfoBuilder().title("Dubbo Demo").description("接口文档").version("1.0.0-SNAPSHOT").build();
    }

    @Override
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/**")
                .addResourceLocations("classpath:/static/");
        registry.addResourceHandler("swagger-ui.html")
                .addResourceLocations("classpath:/META-INF/resources/");
        registry.addResourceHandler("/webjars/**")
                .addResourceLocations("classpath:/META-INF/resources/webjars/");
    }

}

DubboConfiguration

package com.ler.dubbo.demo.config;

import com.alibaba.dubbo.config.ApplicationConfig;
import com.alibaba.dubbo.config.ConsumerConfig;
import com.alibaba.dubbo.config.ProtocolConfig;
import com.alibaba.dubbo.config.RegistryConfig;
import com.alibaba.dubbo.config.spring.context.annotation.DubboComponentScan;
import java.util.HashMap;
import java.util.Map;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

/**
 * @author lww
 * @date 2019-08-17 15:37
 */
@Configuration
//扫描生产者service
@DubboComponentScan(basePackages = "com.ler.dubbo.demo.service.impl")
public class DubboConfiguration {

    /**
     * 当前应用配置
     */
    @Bean
    public ApplicationConfig applicationConfig() {
        ApplicationConfig applicationConfig = new ApplicationConfig();
        //应用名字
        applicationConfig.setName("dubbo-demo");
        Map<String, String> parameters = new HashMap<>(16);
        //qos打开,一台机上多个项目时,可能会造成端口冲突
        parameters.put("qos.enable", "false");
        applicationConfig.setParameters(parameters);
        return applicationConfig;
    }

    /**
     * 连接注册中心配置
     */
    @Bean
    public RegistryConfig registryConfig() {
        RegistryConfig registryConfig = new RegistryConfig();
        //协议
        registryConfig.setProtocol("zookeeper");
        //zk地址
        registryConfig.setAddress("127.0.0.1:2181");
        //缓存存放路径
        registryConfig.setFile("dubbo.cache");
        //whether to export service on the register center
        registryConfig.setRegister(true);
        registryConfig.setClient("curator");
        return registryConfig;
    }

    /**
     * 服务提供者协议配置
     */
    @Bean
    public ProtocolConfig protocolConfig() {
        ProtocolConfig protocolConfig = new ProtocolConfig();
        //协议名字 还有其他的,感兴趣的可以去搜一下看看 rmi协议,hessian协议,thrift协议,http协议
        protocolConfig.setName("dubbo");
        //service port,-1 随机端口
        protocolConfig.setPort(-1);
        //thread pool size (fixed size)
        protocolConfig.setThreads(100);
        return protocolConfig;
    }

    /**
     * 消费者统一设置
     */
    @Bean
    public ConsumerConfig consumerConfig() {
        ConsumerConfig consumerConfig = new ConsumerConfig();
        //超时时间
        consumerConfig.setTimeout(3000);
        //启动检查
        consumerConfig.setCheck(false);
        //懒加载
        consumerConfig.setLazy(true);
        return consumerConfig;
    }
}

生产者

  • Domain
package com.ler.dubbo.api.domain;

import java.io.Serializable;
import lombok.Data;

/**
 * @author lww
 * @date 2019-08-17 15:42
 */
@Data
public class User implements Serializable {

    private static final long serialVersionUID = 1L;

    private String name;

    private Integer age;

}

  • Service
package com.ler.dubbo.api.service;

import com.ler.dubbo.api.domain.User;

/**
 * @author lww
 * @date 2019-08-17 15:41
 */
public interface UserService {

    User getUser();
}

  • ServiceImpl
package com.ler.dubbo.demo.service.impl;

import com.alibaba.dubbo.config.annotation.Service;
import com.ler.dubbo.api.domain.User;
import com.ler.dubbo.api.service.UserService;

/**
 * @author lww
 * @date 2019-08-17 15:53
 */
 //Dubbo的Service注解,此处的timeout优先级更高
@Service(timeout = 5000)
//@Component 可以使用Spring的@Component注解,来让Spring来管理。因为测试Dubbo不用这个注解
public class UserServiceImpl implements UserService {

    @Override
    public User getUser() {
        User user = new User();
        user.setName("Hello Dubbo!");
        user.setAge(123);
        try {
            Thread.sleep(4000);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }
        return user;
    }

}

消费者

  • Service
package com.ler.dubbo.demo.service;

import com.ler.dubbo.api.domain.User;

public interface LocalUserService {

    User getUser();
}

  • ServiceImpl
package com.ler.dubbo.demo.service.impl;

import com.alibaba.dubbo.config.annotation.Reference;
import com.ler.dubbo.api.domain.User;
import com.ler.dubbo.api.service.UserService;
import com.ler.dubbo.demo.service.LocalUserService;
import org.springframework.stereotype.Service;

/**
* @author lww
* @date 2019-08-17 16:53
*/
//Spring的Service注解
@Service 
public class LocalUserServiceImpl implements LocalUserService {

   //dubbo注解
   @Reference
   private UserService userService;

   @Override
   public User getUser() {
    User user = userService.getUser();
    return user;
   }
}

  • Controller
package com.ler.dubbo.demo.controller;

import com.ler.dubbo.api.domain.User;
import com.ler.dubbo.demo.result.HttpResult;
import com.ler.dubbo.demo.service.LocalUserService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import javax.annotation.Resource;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

/**
 * @author lww
 * @date 2019-08-17 16:55
 */
@Api(value = "/", description = "用户相关")
@RequestMapping("/")
@RestController
public class UserController {

    @Resource
    private LocalUserService localUserService;

    @ApiOperation("获取用户")
    @GetMapping("/user")
    public HttpResult getUser() {
        User user = localUserService.getUser();
        return HttpResult.success(user);
    }
}

  • 超时时间统一设置为3秒,睡眠4秒

    89_9.png

  • 在方法上设置为5秒,修改后要重启,才能看到效果

    89_10.png

  • 响应正常

    89_11.png

总结

下面是项目代码 项目源码

文章永久链接:https://tech.souyunku.com/33767

未经允许不得转载:搜云库技术团队 » ZooKeeper与Dubbo注解配置

JetBrains 全家桶,激活、破解、教程

提供 JetBrains 全家桶激活码、注册码、破解补丁下载及详细激活教程,支持 IntelliJ IDEA、PyCharm、WebStorm 等工具的永久激活。无论是破解教程,还是最新激活码,均可免费获得,帮助开发者解决常见激活问题,确保轻松破解并快速使用 JetBrains 软件。获取免费的破解补丁和激活码,快速解决激活难题,全面覆盖 2024/2025 版本!

联系我们联系我们