概述:Consul 是HashiCorp 公司推出的一款基于Go语言编写的用于实现分布式系统服务发现与配置的一款开源工具。Consul主要功能包含服务注册与发现、分布式一致性协议(Raft算法)实现、监控检查、Key/Value存储、多数据中心方案。本章将介绍consul的单机安装以及生产者消费者工程注册服务并工程间进行http调用。
一、Consul的单机版安装与启动
1,首先我们下载consul的安装包,下载地址 https://www.consul.io/downloads 我们选择 linux 64位,这个根据自身环境选择下载。
2,将下载的安装包上传并进行解压到linux系统上,并使用unzip 命令进行解压 unzip consul_1.8.6_linux_amd64.zip ,解压后将出现一个consul 文件。
3,开发者模式启动单节点的consul 服务,使用命令:./consul agent -dev -client=0.0.0.0 &,查看版本信息使用命令 ./consul -version
4,访问consul控制台 查看启动情况,访问地址:http://192.168.17.128:8500/ui ip为linux主机地址,成功后访问如下:
二、SpringBoot生产者工程服务注册到Consul注册中心中
在上面的步骤中我们在linux 上成功安装了consul 注册中心,接下来我们创建一个简单的生产者服务工程并注册到consul注册中心中去。
生产者子模块完整目录:
1,创建一个maven 父工程SpringCloud,并配置其pom文件,设置其为SpringBoot工程,并指定相关的依赖版本控制。pom.xml 如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.xiaohui.springCloud</groupId>
<artifactId>SpringCloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.2.RELEASE</version>
</parent>
<!-- modules 为子模块,当创建子模块后自动会生成 -->
<modules>
<module>cloud-api-common</module>
<module>consul_product_service</module>
<module>consul_order_service</module>
</modules>
<!-- 统一jar包管理 -->
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<maven.compiler.source>1.8</maven.compiler.source>
<maven.compiler.target>1.8</maven.compiler.target>
<junit.version>4.12</junit.version>
<log4j.version>1.2.17</log4j.version>
<lombok.version>1.16.18</lombok.version>
<mysql.version>5.1.47</mysql.version>
<druid.version>1.1.16</druid.version>
<mybatis.spring.boot.version>1.3.0</mybatis.spring.boot.version>
</properties>
<!-- 子模块继承之后,提供作用:锁定版本+子模块不用写groupId和version -->
<dependencyManagement>
<dependencies>
<!-- spring cloud Hoxton.SR1 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR1</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!-- springcloud alibaba -->
<dependency>
<groupId>com.alibaba.cloud</groupId>
<artifactId>spring-cloud-alibaba-dependencies</artifactId>
<version>2.1.0.RELEASE</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>com.alibaba</groupId>
<artifactId>druid</artifactId>
<version>${druid.version}</version>
</dependency>
<dependency>
<groupId>org.mybatis.spring.boot</groupId>
<artifactId>mybatis-spring-boot-starter</artifactId>
<version>${mybatis.spring.boot.version}</version>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>${junit.version}</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>${lombok.version}</version>
<optional>true</optional>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<!-- maven 插件 -->
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<configuration>
<fork>true</fork>
<addResources>true</addResources>
</configuration>
</plugin>
</plugins>
</build>
</project>
2,创建实体类公用项目maven子模块参考代码链接 SpringCloud项目之实体类子模块
3,创建生产者服务子模块 模块命名其为 consul_product_service ,并加入web、consul、actuator、公共模块等依赖。完整pom文件如下:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloud</artifactId>
<groupId>com.xiaohui.springCloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consul_product_service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>com.xiaohui.springCloud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- springCloud 提供基于consul的服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--SpringBoot actuator健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
4,创建生产者工程配置文件 application.yml:
server:
port: 9001
spring:
application:
name: service-product
#consul 信息配置
cloud:
consul:
host: 192.168.17.128 #consul注册中心的ip地址
port: 8500 #consul注册中心端口
discovery:
register: true #是否需要注册
instance-id: ${spring.application.name}-1 #实例id(唯一标志)
service-name: ${spring.application.name} #服务的名称
prefer-ip-address: true #开启ip地址注册
ip-address: ${spring.cloud.client.ip-address} #当前服务的请求ip
port: ${server.port} #服务的请求端口
5,创建生产者工程主启动类 com.xiaohui.consul.ProductApplication.java
package com.xiaohui.consul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProductApplication {
public static void main(String[] args) {
SpringApplication.run(ProductApplication.class,args);
}
}
6,controller、service等代码实现
com.xiaohui.consul.controller.ProductController
package com.xiaohui.consul.controller;
import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.entities.Payment;
import com.xiaohui.consul.service.IProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.*;
@RestController
public class ProductController {
@Autowired
IProductService productService;
@Value("${spring.cloud.client.ip-address}")
private String ip;
@Value("${server.port}")
private String port;
@PostMapping("/product/create")
public CommonResult insert(@RequestBody Payment payment){
int id = productService.insert(payment);
if(id > 0){
return new CommonResult(0,"插入成功",id);
}else{
return new CommonResult(-9999,"插入失败",id);
}
}
@GetMapping("/product/get/{id}")
public CommonResult getPaymentById(@PathVariable("id") Long id){
Payment payment = productService.getPaymentById(id);
if(payment != null){
return new CommonResult(0,"查询成功 server node:"+ip+":"+port,payment);
}else{
return new CommonResult(-9999,"查询失败,不存在信息 server node:"+ip+":"+port,null);
}
}
}
service:com.xiaohui.consul.service.IProductService
package com.xiaohui.consul.service;
import com.xiaohui.springcloud.entities.Payment;
public interface IProductService {
public int insert(Payment payment);
/**
* 查询
* @param id
* @return
*/
public Payment getPaymentById(Long id);
}
接口实现:com.xiaohui.consul.service.impl.ProductServiceImpl
package com.xiaohui.consul.service.impl;
import com.xiaohui.consul.service.IProductService;
import com.xiaohui.springcloud.entities.Payment;
import com.xiaohui.consul.service.IProductService;
import org.springframework.stereotype.Service;
import javax.annotation.Resource;
@Service
public class ProductServiceImpl implements IProductService {
@Override
public int insert(Payment payment) {
return 10086;
}
@Override
public Payment getPaymentById(Long id) {
Payment payment = new Payment(id,"订单描述信息。。");
return payment;
}
}
三、SpringBoot消费者工程接入Consul获取发现服务
消费者工程接入并实现http调用,在consul中与Eureka一样同样集成了ribbon功能,使用RestTemplate 进行http调用。消费者工程整体目录结构如下:
搭建步骤:
1,与生产者一样创建子模块,配置pom文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<parent>
<artifactId>SpringCloud</artifactId>
<groupId>com.xiaohui.springCloud</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>consul_order_service</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<!-- 公共模块 -->
<dependency>
<groupId>com.xiaohui.springCloud</groupId>
<artifactId>cloud-api-common</artifactId>
<version>${project.version}</version>
</dependency>
<!-- springCloud 提供基于consul的服务发现 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<!--SpringBoot actuator健康检查 -->
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
</dependencies>
</project>
2,创建application.yml 配置文件,并指定服务端口,应用名称,consul相关配置信息
server:
port: 8001
spring:
application:
name: order-service
cloud:
#consul 注册中心信息配置
consul:
host: 192.168.17.128 #consul注册中心的ip地址
port: 8500 #consul注册中心端口
discovery:
register: true #是否需要注册
instance-id: ${spring.application.name}-1 #实例id(唯一标志)
service-name: ${spring.application.name} #服务的名称
prefer-ip-address: true #开启ip地址注册
ip-address: ${spring.cloud.client.ip-address} #当前服务的请求ip
port: ${server.port} #服务的请求端口
3,创建主启动类com.xiaohui.consul.OrderApplication
package com.xiaohui.consul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class,args);
}
}
4,添加配置类,对RestTemplate对象进行注入,注意在RestTemplate的注入方法上添加@LoadBalanced注解后,则可以使用ribbon的负载均衡功能,以及调用时使用服务名代替ip地址。
package com.xiaohui.consul.config;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
/**
*
* 相当于 spring的 application.xml bean注解相当于 bean 标签
*/
@Configuration
public class ApplicationContextConfig {
@LoadBalanced
@Bean
public RestTemplate getRestTemplate(){
return new RestTemplate();
}
}
5,controller类如下,在该类中使用RestTemplate对象进行http调用
package com.xiaohui.consul.controller;
import com.xiaohui.springcloud.entities.CommonResult;
import com.xiaohui.springcloud.entities.Payment;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
@RestController
public class OrderController {
public static String PAYMENT_URL = "http://127.0.0.1:9001";
@Autowired
private RestTemplate restTemplate;
@GetMapping("/consumer/product/get/{id}")
public CommonResult<Payment> getProduct(@PathVariable("id") Long id){
return restTemplate.getForObject("http://service-product/product/get/"+id,CommonResult.class);
}
}
四、启动并进行测试调用
分别启动生产者和消费者服务工程,并在consul控制台页面查看:
访问测试,调用返回正常如下: