consul的具体安装与操作查看博客的consul系列。

一、启动consul

(1个server+1个client,方便起见,client使用本机):查看:http://www.cnblogs.com/java-zhao/p/5375132.html

1、开启虚拟机-->切换到vagrantFile中配置的节点

  • vagrant up
  • vagrant ssh n110

2、启动server(n110)

  • consul agent -server -bootstrap-expect=1  -data-dir=/tmp/consul -node=server-110 -bind=192.168.21.110 -dc=zjgdc1 -client 0.0.0.0 -ui

说明:-client 0 0 0 0 -ui-->使得客户端可以直接通过url访问服务端的consul ui

3、启动client(local)

  • consul agent -data-dir=/tmp/consul -node=client-my -bind=xxx -dc=zjgdc1

说明:xxx代表本机IP

4、client加入server

  • consul join 192.168.21.110

二、java部分

1、pom.xml

<!-- consul-client -->
        <dependency>
            <groupId>com.orbitz.consul</groupId>
            <artifactId>consul-client</artifactId>
            <version>0.10.0</version>
        </dependency>
        <!-- consul需要的包 -->
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-client</artifactId>
            <version>2.22.2</version>
        </dependency>

说明:consul的java客户端有两个:consul-client和consul-api。

consul-client的github地址:https://github.com/OrbitzWorldwide/consul-client

2、ConsulService

package com.xxx.firstboot.service;

import java.net.MalformedURLException;
import java.net.URI;
import java.util.List;

import org.springframework.stereotype.Service;

import com.orbitz.consul.AgentClient;
import com.orbitz.consul.Consul;
import com.orbitz.consul.HealthClient;
import com.orbitz.consul.KeyValueClient;
//import com.orbitz.consul.NotRegisteredException;
import com.orbitz.consul.StatusClient;
import com.orbitz.consul.model.health.ServiceHealth;

@Service
public class ConsulService {

    /**
     * 注册服务
     * 并对服务进行健康检查
     * servicename唯一
     * serviceId:没发现有什么作用
     */
    public void registerService(String serviceName, String serviceId) {
        Consul consul = Consul.builder().build();            //建立consul实例
        AgentClient agentClient = consul.agentClient();        //建立AgentClient

        try {
            /**
             * 注意该注册接口:
             * 需要提供一个健康检查的服务URL,以及每隔多长时间访问一下该服务(这里是3s)
             */
            agentClient.register(8080, URI.create("http://localhost:8080/health").toURL(), 3, serviceName, serviceId, "dev");
        } catch (MalformedURLException e) {
            e.printStackTrace();
        }
//        try {
//            agentClient.pass(serviceId);//健康检查
//        } catch (NotRegisteredException e) {
//            e.printStackTrace();
//        }
    }

    /**
     * 发现可用的服务
     */
    public List<ServiceHealth> findHealthyService(String servicename){
        Consul consul = Consul.builder().build();
        HealthClient healthClient = consul.healthClient();//获取所有健康的服务
        return healthClient.getHealthyServiceInstances(servicename).getResponse();//寻找passing状态的节点
    }

    /**
     * 存储KV
     */
    public void storeKV(String key, String value){
        Consul consul = Consul.builder().build();
        KeyValueClient kvClient = consul.keyValueClient();
        kvClient.putValue(key, value);//存储KV
    }

    /**
     * 根据key获取value
     */
    public String getKV(String key){
        Consul consul = Consul.builder().build();
        KeyValueClient kvClient = consul.keyValueClient();
        return kvClient.getValueAsString(key).get();
    }

    /**
     * 找出一致性的节点(应该是同一个DC中的所有server节点)
     */
    public List<String> findRaftPeers(){
        StatusClient statusClient = Consul.builder().build().statusClient();
        return statusClient.getPeers();
    }

    /**
     * 获取leader
     */
    public String findRaftLeader(){
        StatusClient statusClient = Consul.builder().build().statusClient();
        return statusClient.getLeader();
    }

}

列出了常用API。

注意:

  • 服务注册的时候不需要传递IP
  • 服务注册的时候需要给出health check的url和时间间隔。该url是一个服务(要提供该服务,需要使用spring boot actuator,具体操作如下:)。

直接在pomx.ml中加入:

         <dependency>
             <groupId>org.springframework.boot</groupId>
             <artifactId>spring-boot-starter-actuator</artifactId>
         </dependency>

此时重启应用后,访问http://localhost:8080/health,得到如下结果一个json串:

{
status: "UP",
diskSpace: - {
status: "UP",
total: 249769230336,
free: 182003318784,
threshold: 10485760
},
rabbit: - {
status: "UP",
version: "3.6.1"
},
mongo: - {
status: "UP",
version: "3.2.6"
},
db: - {
status: "UP",
myTestDbDataSource: - {
status: "UP",
database: "MySQL",
hello: 1
},
myTestDb2DataSource: - {
status: "UP",
database: "MySQL",
hello: 1
},
dataSource: - {
status: "UP",
database: "MySQL",
hello: 1
}
},
_links: - {
self: - {
href: "http://localhost:8080/health"
}
}
}
Format online

说明:status

  • UP:服务器正常(以上只要有一个组件DOWN,服务器就处于DOWN,所以我需要启动服务器上的mongo和rabbitmq,这里我之前使用了这两个组件)
  • DOWN:服务器挂了

3、ConsulController

package com.xxx.firstboot.web;

import java.util.List;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import com.orbitz.consul.model.health.ServiceHealth;
import com.xxx.firstboot.service.ConsulService;

import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;

@Api("consul相关API")
@RestController
@RequestMapping("/consul")
public class ConsulController {
    @Autowired
    private ConsulService consulService;

    /*******************************服务注册与发现*******************************/
    @ApiOperation("注册服务")
    @RequestMapping(value="/registerService/{servicename}/{serviceid}",method=RequestMethod.POST)
    public void registerService(@PathVariable("servicename") String serviceName,
                                @PathVariable("serviceid") String serviceId) {
        consulService.registerService(serviceName, serviceId);
    }

    @ApiOperation("发现服务")
    @RequestMapping(value="/discoverService/{servicename}",method=RequestMethod.GET)
    public List<ServiceHealth> discoverService(@PathVariable("servicename") String serviceName) {
        return consulService.findHealthyService(serviceName);
    }

    /*******************************KV*******************************/
    @ApiOperation("store KV")
    @RequestMapping(value="/kv/{key}/{value}",method=RequestMethod.POST)
    public void storeKV(@PathVariable("key") String key,
                        @PathVariable("value") String value) {
        consulService.storeKV(key, value);
    }

    @ApiOperation("get KV")
    @RequestMapping(value="/kv/{key}",method=RequestMethod.GET)
    public String getKV(@PathVariable("key") String key) {
        return consulService.getKV(key);
    }

    /*******************************server*******************************/
    @ApiOperation("获取同一个DC中的所有server节点")
    @RequestMapping(value="/raftpeers",method=RequestMethod.GET)
    public List<String> findRaftPeers() {
        return consulService.findRaftPeers();
    }

    @ApiOperation("获取leader")
    @RequestMapping(value="/leader",method=RequestMethod.GET)
    public String leader() {
        return consulService.findRaftLeader();
    }
}

4、测试(通过swagger测试+通过consul UI查看结果)

  • swagger:http://localhost:8080/swagger-ui.html
  • consul UI:http://192.168.21.110:8500/ui/

上图展示了consul UI所展示的所有东西。services、nodes、kv、datacenter

【第二十章】 springboot + consul(1)的更多相关文章

  1. 第二十章 springboot + consul(1)

    consul的具体安装与操作查看博客的consul系列. 一.启动consul (1个server+1个client,方便起见,client使用本机):查看:http://www.cnblogs.co ...

  2. JavaScript高级程序设计:第二十章

    第二十章 一.语法 JSON的语法可以表示以下三种类型的值: (1)简单值 (2)对象 JSON的对象与javascript字面量有一些不同.例如,在javascript中,前面的对象字面量可以写成下 ...

  3. 第二十章 Django数据库实战

    第二十章 Django数据库实战 第一课 获取单表单数据的三种方式: urls.py中的路由代码: path('busniess',views.busniess), views.py中代码: def ...

  4. Gradle 1.12翻译——第二十章. 构建环境

    有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...

  5. “全栈2019”Java多线程第二十章:同步方法产生死锁的例子

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...

  6. “全栈2019”Java异常第二十章:自定义异常详解

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...

  7. “全栈2019”Java第二十章:按位与、按位或、异或、反码、位运算

    难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...

  8. 2017.3.14 activiti实战--第二十章--REST服务

    学习资料:<Activiti实战> 第二十章 REST服务 20.1 通信协议概述 略. 20.2 REST API概述 资源分类 资源基础URI 说明 Deployments manag ...

  9. python 教程 第二十章、 数据库编程

    第二十章. 数据库编程 环境设置 1).安装MySQL-python http://www.lfd.uci.edu/~gohlke/pythonlibs/ MySQL-python-1.2.3.win ...

  10. 20190920 On Java8 第二十章 泛型

    第二十章 泛型 多态的泛化机制: 将方法的参数类型设为基类: 方法以接口而不是类作为参数: 使用泛型: 泛型实现了参数化类型 简单泛型 Java 泛型的核心概念:你只需告诉编译器要使用什么类型,剩下的 ...

随机推荐

  1. 匿名内部类的参数引用只能是final,可能遇到的问题及其解决

    这个是我碰到比较多次的问题,一开始是不解,不过查了下大家都觉得没什么,而且只是加个final好像影响也不大,于是我就直接加个final了事,之后也不管了 直到昨天: 遇到了这个宿命般的问题 难道解决方 ...

  2. maven项目创建

    一.搭建步骤 ♦首先创建一个Maven的Project,如下图: ♦点击Next,勾选 Create a simple project ♦点击Next,注意Packing要选择war,因为我们创建的是 ...

  3. python 基础 集合

    集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 交集 并集 差集 子集  对称差集 list ...

  4. 帝国cms栏目别名怎样调用?栏目名称太短了

    在用帝国cms创建栏目时一般会填写栏目名称(较短)和栏目别名(为空则与栏目名相同),栏目别名可以设置长一些作为栏目标题,可是如何调用帝国cms栏目别名呢?默认的模板标题调用是<title> ...

  5. 前m大的数(哈希入门)&&sort

    http://acm.hdu.edu.cn/showproblem.php?pid=1280 普通方法(625ms) #include <stdio.h> #include <str ...

  6. Hive错误:Unable to load native-hadoop library for your platform

    WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin- ...

  7. iis服务器配置

    对应的步骤在文件中上传了rar文件 1 .net framework 4.0 和 framework 4.5 直接安装程序  先安装4.0 再安装4.5 顺序不能颠倒!下载完直接安装 如果有会提示本机 ...

  8. RAC禁用DRM特性

    查看"_gc"开头的隐藏参数值: set linesize 333 col name for a35 col description for a66 col value for a ...

  9. MFC六大核心机制之四:永久保存(串行化)

    永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...

  10. 支持向量机(SVM)中的 SMO算法

    1. 前言 最近又重新复习了一遍支持向量机(SVM).其实个人感觉SVM整体可以分成三个部分: 1. SVM理论本身:包括最大间隔超平面(Maximum Margin Classifier),拉格朗日 ...