【第二十章】 springboot + consul(1)
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)的更多相关文章
- 第二十章 springboot + consul(1)
consul的具体安装与操作查看博客的consul系列. 一.启动consul (1个server+1个client,方便起见,client使用本机):查看:http://www.cnblogs.co ...
- JavaScript高级程序设计:第二十章
第二十章 一.语法 JSON的语法可以表示以下三种类型的值: (1)简单值 (2)对象 JSON的对象与javascript字面量有一些不同.例如,在javascript中,前面的对象字面量可以写成下 ...
- 第二十章 Django数据库实战
第二十章 Django数据库实战 第一课 获取单表单数据的三种方式: urls.py中的路由代码: path('busniess',views.busniess), views.py中代码: def ...
- Gradle 1.12翻译——第二十章. 构建环境
有关其他已翻译的章节请关注Github上的项目:https://github.com/msdx/gradledoc/tree/1.12,或访问:http://gradledoc.qiniudn.com ...
- “全栈2019”Java多线程第二十章:同步方法产生死锁的例子
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java多 ...
- “全栈2019”Java异常第二十章:自定义异常详解
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java异 ...
- “全栈2019”Java第二十章:按位与、按位或、异或、反码、位运算
难度 初级 学习时间 10分钟 适合人群 零基础 开发语言 Java 开发环境 JDK v11 IntelliJ IDEA v2018.3 文章原文链接 "全栈2019"Java第 ...
- 2017.3.14 activiti实战--第二十章--REST服务
学习资料:<Activiti实战> 第二十章 REST服务 20.1 通信协议概述 略. 20.2 REST API概述 资源分类 资源基础URI 说明 Deployments manag ...
- python 教程 第二十章、 数据库编程
第二十章. 数据库编程 环境设置 1).安装MySQL-python http://www.lfd.uci.edu/~gohlke/pythonlibs/ MySQL-python-1.2.3.win ...
- 20190920 On Java8 第二十章 泛型
第二十章 泛型 多态的泛化机制: 将方法的参数类型设为基类: 方法以接口而不是类作为参数: 使用泛型: 泛型实现了参数化类型 简单泛型 Java 泛型的核心概念:你只需告诉编译器要使用什么类型,剩下的 ...
随机推荐
- 匿名内部类的参数引用只能是final,可能遇到的问题及其解决
这个是我碰到比较多次的问题,一开始是不解,不过查了下大家都觉得没什么,而且只是加个final好像影响也不大,于是我就直接加个final了事,之后也不管了 直到昨天: 遇到了这个宿命般的问题 难道解决方 ...
- maven项目创建
一.搭建步骤 ♦首先创建一个Maven的Project,如下图: ♦点击Next,勾选 Create a simple project ♦点击Next,注意Packing要选择war,因为我们创建的是 ...
- python 基础 集合
集合 集合是一个无序的,不重复的数据组合,它的主要作用如下: 去重,把一个列表变成集合,就自动去重了 关系测试,测试两组数据之前的交集.差集.并集等关系 交集 并集 差集 子集 对称差集 list ...
- 帝国cms栏目别名怎样调用?栏目名称太短了
在用帝国cms创建栏目时一般会填写栏目名称(较短)和栏目别名(为空则与栏目名相同),栏目别名可以设置长一些作为栏目标题,可是如何调用帝国cms栏目别名呢?默认的模板标题调用是<title> ...
- 前m大的数(哈希入门)&&sort
http://acm.hdu.edu.cn/showproblem.php?pid=1280 普通方法(625ms) #include <stdio.h> #include <str ...
- Hive错误:Unable to load native-hadoop library for your platform
WARN util.NativeCodeLoader: Unable to load native-hadoop library for your platform... using builtin- ...
- iis服务器配置
对应的步骤在文件中上传了rar文件 1 .net framework 4.0 和 framework 4.5 直接安装程序 先安装4.0 再安装4.5 顺序不能颠倒!下载完直接安装 如果有会提示本机 ...
- RAC禁用DRM特性
查看"_gc"开头的隐藏参数值: set linesize 333 col name for a35 col description for a66 col value for a ...
- MFC六大核心机制之四:永久保存(串行化)
永久保存(串行化)是MFC的重要内容,可以用一句简明直白的话来形容其重要性:弄懂它以后,你就越来越像个程序员了! 如果我们的程序不需要永久保存,那几乎可以肯定是一个小玩儿.那怕我们的记事本.画图等小程 ...
- 支持向量机(SVM)中的 SMO算法
1. 前言 最近又重新复习了一遍支持向量机(SVM).其实个人感觉SVM整体可以分成三个部分: 1. SVM理论本身:包括最大间隔超平面(Maximum Margin Classifier),拉格朗日 ...