Consul
Consul 是由 HashiCorp 開發(fā)的一款軟件工具,提供了一組功能,用于服務(wù)發(fā)現(xiàn)、配置管理和網(wǎng)絡(luò)基礎(chǔ)設(shè)施自動(dòng)化。它旨在幫助組織管理現(xiàn)代分布式和微服務(wù)架構(gòu)系統(tǒng)的復(fù)雜性。以下是Consul的一些關(guān)鍵方面和功能:
服務(wù)發(fā)現(xiàn):Consul 允許服務(wù)自行注冊(cè)并以動(dòng)態(tài)和自動(dòng)化的方式發(fā)現(xiàn)其他服務(wù)。這在微服務(wù)架構(gòu)中特別重要,因?yàn)榉?wù)需要定位并與其他服務(wù)通信。
健康檢查:Consul 可以對(duì)已注冊(cè)的服務(wù)執(zhí)行健康檢查。如果服務(wù)變得不健康,Consul 可以自動(dòng)更新其路由,以避免將流量發(fā)送到該服務(wù),直到它再次變得健康。
鍵值存儲(chǔ):Consul 包括分布式鍵值存儲(chǔ),可用于動(dòng)態(tài)配置、特性標(biāo)志和其他需要在服務(wù)之間共享的數(shù)據(jù)。
安全通信:Consul 支持安全通信,可用于保護(hù)服務(wù)之間的通信,確保數(shù)據(jù)的機(jī)密性和完整性。
Consul 是一種強(qiáng)大的工具,可幫助組織更好地管理其分布式系統(tǒng)和微服務(wù)架構(gòu)中的各種方面。
學(xué)習(xí)如何使用Consul需要掌握一些基本概念和實(shí)踐技巧。以下是學(xué)習(xí)Consul的步驟:
基本概念與原理
consul的角色
Consul 有三種主要的角色:開發(fā)者 (Dev)、客戶端 (Client) 和服務(wù)器 (Server)。這些角色用于組織 Consul 集群中的節(jié)點(diǎn),以實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)、健康檢查和鍵值存儲(chǔ)等功能。以下是對(duì)這三種角色的簡(jiǎn)要描述:
開發(fā)者角色 (Dev):
開發(fā)者角色通常用于本地開發(fā)和測(cè)試環(huán)境,而不是生產(chǎn)環(huán)境。
在開發(fā)者角色下,Consul代理以開發(fā)模式啟動(dòng),不需要連接到其他Consul節(jié)點(diǎn)。這使得它們能夠在單獨(dú)的節(jié)點(diǎn)上運(yùn)行,用于本地服務(wù)發(fā)現(xiàn)和開發(fā)目的。
開發(fā)者角色不適用于構(gòu)建生產(chǎn)用的Consul集群,因?yàn)樗鼈儾痪邆涓呖捎眯院腿哂唷?br> 客戶端角色 (Client): 代理,接受http或者DNS請(qǐng)求信息,轉(zhuǎn)發(fā)給server
客戶端角色是Consul集群中的節(jié)點(diǎn)之一,它們負(fù)責(zé)與其他節(jié)點(diǎn)通信,并可以用于執(zhí)行DNS或HTTP API查詢。
客戶端節(jié)點(diǎn)向服務(wù)器節(jié)點(diǎn)發(fā)送查詢請(qǐng)求,以查找和發(fā)現(xiàn)服務(wù)。它們通常部署在應(yīng)用程序服務(wù)器上,以便應(yīng)用程序可以利用Consul的服務(wù)發(fā)現(xiàn)功能。
客戶端節(jié)點(diǎn)不具備存儲(chǔ)集群數(shù)據(jù)的功能,但可以將查詢請(qǐng)求路由到服務(wù)器節(jié)點(diǎn)來獲取有關(guān)服務(wù)的信息。
服務(wù)器角色 (Server):3-5個(gè)
服務(wù)器角色是Consul集群的核心,負(fù)責(zé)存儲(chǔ)集群的狀態(tài)信息,執(zhí)行健康檢查,并協(xié)調(diào)服務(wù)注冊(cè)和發(fā)現(xiàn)。
服務(wù)器節(jié)點(diǎn)通常以多節(jié)點(diǎn)的方式部署,以確保高可用性和冗余。這些節(jié)點(diǎn)組成了Consul集群的核心,保持一致的狀態(tài)信息。
服務(wù)器節(jié)點(diǎn)還可以配置數(shù)據(jù)中心之間的復(fù)制和通信,以實(shí)現(xiàn)全局的服務(wù)發(fā)現(xiàn)和協(xié)調(diào)。
原理
了解什么是服務(wù)發(fā)現(xiàn)、健康檢查和分布式鍵值存儲(chǔ),這是Consul的核心概念。
服務(wù)發(fā)現(xiàn)及注冊(cè):
producer啟動(dòng)時(shí),會(huì)將自己的ip/host等信息通過發(fā)送請(qǐng)求告知consul,consul接收到producer的注冊(cè)信息后,每隔10秒(默認(rèn))會(huì)向producer發(fā)送一個(gè)健康檢查的請(qǐng)求,檢查producer是否處于可用狀態(tài),防止consumer調(diào)到不可用的服務(wù);
服務(wù)調(diào)用
當(dāng)consumer請(qǐng)求product時(shí),會(huì)先從consul中拿存儲(chǔ)的producer服務(wù)的ip和port的臨時(shí)表(temp table),從表中任選一個(gè)producer的ip和port,然后根據(jù)這個(gè)ip和port,發(fā)送訪問請(qǐng)求;此表只包含通過健康檢查的producer信息,并且每隔10秒更新。。
服務(wù)發(fā)現(xiàn)
服務(wù)發(fā)現(xiàn)是指在分布式系統(tǒng)或微服務(wù)架構(gòu)中,自動(dòng)地發(fā)現(xiàn)并識(shí)別可用的服務(wù)實(shí)例。這是因?yàn)樵谶@樣的環(huán)境中,服務(wù)實(shí)例的數(shù)量和位置通常是動(dòng)態(tài)的。
服務(wù)發(fā)現(xiàn)系統(tǒng)允許服務(wù)注冊(cè)它們自己,以及查詢已注冊(cè)的其他服務(wù)。這有助于應(yīng)用程序找到其依賴的服務(wù),并確保它們可以相互通信。
健康檢查
健康檢查是一種機(jī)制,用于監(jiān)視服務(wù)的狀態(tài)和可用性。服務(wù)可以定期進(jìn)行自我檢查,并向服務(wù)發(fā)現(xiàn)系統(tǒng)報(bào)告它們的健康狀態(tài)。
如果服務(wù)不再健康,它可以從服務(wù)發(fā)現(xiàn)系統(tǒng)中注銷,從而不再接收流量。這有助于系統(tǒng)自動(dòng)處理故障,并確??蛻舳瞬粫?huì)請(qǐng)求到不正常的服務(wù)。
分布式鍵值存儲(chǔ)
分布式鍵值存儲(chǔ)是一種數(shù)據(jù)存儲(chǔ)系統(tǒng),允許應(yīng)用程序?qū)㈡I值對(duì)存儲(chǔ)在一個(gè)分布式的、可擴(kuò)展的數(shù)據(jù)存儲(chǔ)中。
這種數(shù)據(jù)存儲(chǔ)通常具有高可用性,并可用于存儲(chǔ)配置數(shù)據(jù)、應(yīng)用程序狀態(tài)、特性標(biāo)志等信息。分布式鍵值存儲(chǔ)還可以用于協(xié)調(diào)和同步分布式系統(tǒng)的操作。
代理(Agent)
代理是Consul的核心組件之一,運(yùn)行在每個(gè)部署了Consul的節(jié)點(diǎn)上。
代理負(fù)責(zé)與其他節(jié)點(diǎn)通信,定期報(bào)告節(jié)點(diǎn)的健康狀態(tài),執(zhí)行本地健康檢查,以及協(xié)調(diào)服務(wù)注冊(cè)和發(fā)現(xiàn)。
代理還可以執(zhí)行DNS或HTTP API查詢,以便其他應(yīng)用程序可以查找和訪問已注冊(cè)的服務(wù)。
數(shù)據(jù)中心(Datacenter)
數(shù)據(jù)中心是一個(gè)邏輯隔離的單元,通常用于表示不同的部署區(qū)域或環(huán)境。
在一個(gè)大型的分布式系統(tǒng)中,可能有多個(gè)數(shù)據(jù)中心,每個(gè)數(shù)據(jù)中心包含一組Consul代理。
數(shù)據(jù)中心之間可以相互通信,但它們通常是獨(dú)立的,可以有不同的配置和健康檢查策略。
服務(wù)注冊(cè)(Service Registration)
服務(wù)注冊(cè)是Consul的一個(gè)功能,允許應(yīng)用程序注冊(cè)自己的服務(wù)實(shí)例,以便其他應(yīng)用程序可以發(fā)現(xiàn)并與之通信。
當(dāng)一個(gè)服務(wù)啟動(dòng)時(shí),它會(huì)通過Consul代理向Consul集群注冊(cè)自己的服務(wù)信息,包括服務(wù)名稱、IP地址、端口等。
注冊(cè)的服務(wù)信息存儲(chǔ)在Consul的目錄中,供其他應(yīng)用程序查詢。
還有其他服務(wù)注冊(cè)工具
!
安裝Consul
下載和安裝Consul,可以選擇適合你操作系統(tǒng)的版本。
官網(wǎng):consul
windows(dev方式)
目錄中會(huì)得到一個(gè)consul.exe文件
cd到對(duì)應(yīng)的目錄下,使用cmd啟動(dòng)consul:
#-dev表示開發(fā)模式運(yùn)行,另外還有-server表示服務(wù)模式運(yùn)行
consul agent -dev -client=0.0.0.0
為了方便啟動(dòng),也可以在consul.exe同級(jí)目錄下創(chuàng)建一個(gè)腳本(xx.bat)來啟動(dòng),腳本內(nèi)容如下:
consul agent -dev -client=0.0.0.00
pause
訪問管理后臺(tái):http://localhost:8500,能看到正常界面即表示consul服務(wù)啟動(dòng)成功了
tips:-client=0.0.0.0表示允許所有ip訪問
linux
環(huán)境準(zhǔn)備
服務(wù)器ip consul類型 node節(jié)點(diǎn) 系統(tǒng)
192.168.10.101 server server-01 centos
192.168.10.102 server server-02 centos
192.168.10.103 server server-03 centos
192.168.10.1 client client-01 windows
安裝
yum -y install unzip
mkcir -p /usr/local/consul
unzip consul_1.7.0_linux_amd64.zip -d /usr/local/consul/
consul數(shù)據(jù)目錄
mkdir -p /usr/local/consul/data
啟動(dòng)
注冊(cè)中心服務(wù)端:
分別在3臺(tái)server上(/usr/local/consul目錄)執(zhí)行以下命令(-bind及-node改為對(duì)應(yīng)的即可)
./consul agent -server -bind=192.168.10.101 -client=0.0.0.0 -ui -bootstrap-expect=3 -data-dir=/usr/local/consul/data/ -node=server-01
3臺(tái)server上執(zhí)行以下命令:指定101為主節(jié)點(diǎn)
./consul join 192.168.10.101
參數(shù)含義如下:
-server:以服務(wù)端身份啟動(dòng)(注冊(cè)中心)
-bind:表示綁定以哪個(gè)ip
-client:指定客戶端訪問的ip,0.0.0.0不限制客戶端ip
注冊(cè)中心服務(wù)端:
在windows下的consul.exe所在目錄中執(zhí)行,-data-dir對(duì)應(yīng)目錄先建好
consul agent -client=0.0.0.0 -bind=192.168.10.1 -data-dir=D:\consul\data -node=client-01
consul join 192.168.10.101
linux/windows上查看集群狀態(tài)
./consul members
訪問
訪問任務(wù)一個(gè)server的8500端口即可
如:http://192.168.0.101:8500
docker
這是在window下部署consul集群的yaml文件
加紅部分:
目錄先建好,網(wǎng)絡(luò)名改為自己的即可
主要參數(shù)說明:
參數(shù)名 解釋
-server 設(shè)置為 Server 類型節(jié)點(diǎn),不加則為 Client 類型節(jié)點(diǎn)
-client 注冊(cè)或者查詢等一系列客戶端對(duì)它操作的IP,默認(rèn)是127.0.0.1
-bootstrap-expect 集群期望的 Server 節(jié)點(diǎn)數(shù),只有達(dá)到這個(gè)值才會(huì)選舉 Leader
-node 指定節(jié)點(diǎn)名稱
-data-dir 數(shù)據(jù)存放位置
-retry-join 指定要加入的節(jié)點(diǎn)地址(組建集群)
-ui 啟用 UI 界面
version: '3.4'
services:
consul-server1:
image: consul
command: agent -server -client=0.0.0.0 -bootstrap-expect=3 -node=consul-server1 -data-dir=/data
volumes:
- F:/consul/data/server1:/data
consul-server2:
image: consul
command: agent -server -client=0.0.0.0 -retry-join=consul-server1 -node=consul-server2 -data-dir=/data
volumes:
- F:/consul/data/server2:/data
depends_on:
- consul-server1
consul-server3:
image: consul
command: agent -server -client=0.0.0.0 -retry-join=consul-server1 -node=consul-server3 -data-dir=/data
volumes:
- F:/consul/data/server3:/data
depends_on:
- consul-server1
consul-clicent1:
image: consul
command: agent -client=0.0.0.0 -retry-join=consul-server1 -ui -node=consul-client1 -data-dir=/data
ports:
- 8500:8500
volumes:
- F:/consul/data/client1:/data
depends_on:
- consul-server2
- consul-server3
networks:
default:
name: hurong_www_gitee_127.0.0.1 #使用laravel項(xiàng)目中生成的網(wǎng)絡(luò)
external: true #使用已存在的網(wǎng)絡(luò)
#driver: bridge
編寫一個(gè)簡(jiǎn)單的應(yīng)用程序,并將其配置為注冊(cè)到Consul
引入父依賴
新建consule-demo
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
</dependencies>
<properties>
<maven.compiler.source>8</maven.compiler.source>
<maven.compiler.target>8</maven.compiler.target>
<spring-cloud-version>Hoxton.SR1</spring-cloud-version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Hoxton.SR10</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
新建module,service-provider
依賴
<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/maven-v4_0_0.xsd">
<parent>
<artifactId>consul-demo</artifactId>
<groupId>org.example</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<name>service-provider</name>
<description>服務(wù)提供者</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-consul-discovery</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>2.2.4.RELEASE</version>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>RELEASE</version>
<scope>compile</scope>
</dependency>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
<version>1.18.30</version>
</dependency>
</dependencies>
</project>
引入配置application.yml
server:
port: 7070
spring:
application:
name: service-provider
cloud:
consul:
host: localhost
port: 8500
discovery:
register: true
instance-id: ${spring.application.name}-01
service-name: ${spring.application.name}
port: ${server.port}
prefer-ip-address: true
ip-address: localhost
實(shí)體類Product:
package org.example.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.io.Serializable;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Product implements Serializable {
private Integer id;
private String produceName;
private Integer produceNum;
private Double producePrice;
}
服務(wù)層ProductService
package org.example.service;
import org.example.entity.Product;
import java.util.List;
public interface ProductService {
public List<Product> selectProductList();
}
package org.example.service.impl;
import org.example.entity.Product;
import org.example.service.ProductService;
import org.springframework.stereotype.Service;
import java.util.Arrays;
import java.util.List;
@Service
public class ProductServiceImpl implements ProductService {
@Override
public List<Product> selectProductList() {
System.out.println("query product");
return Arrays.asList(
new Product(1,"小米",1,5100D),
new Product(2,"中興",12,5100D)
);
}
}
Controller層
package org.example.controller;
import org.example.entity.Product;
import org.example.service.ProductService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
@RestController
@RequestMapping(value = "/product")
public class ProductController {
@Autowired
ProductService productService;
@GetMapping(value = "/list")
public List<Product> selectProduceList(){
return productService.selectProductList();
}
}
啟動(dòng)文件ProviderApp
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@SpringBootApplication
public class ProviderApp {
public static void main(String[] args) {
SpringApplication.run(ProviderApp.class, args);
}
}
訪問localhost:7070/product/list即可
新建module,service-consumer
依賴與service-provider一樣,配置修改接口和register(是否注冊(cè))
server:
port: 9090
spring:
application:
name: service-consumer
cloud:
consul:
host: localhost
port: 8500
discovery:
register: false
instance-id: ${spring.application.name}-01
service-name: ${spring.application.name}
port: ${server.port}
prefer-ip-address: true
ip-address: localhost
實(shí)體類,Product,復(fù)制上面
Order
package org.example.entity;
import lombok.AllArgsConstructor;
import lombok.Data;
import lombok.NoArgsConstructor;
import java.util.List;
@Data
@NoArgsConstructor
@AllArgsConstructor
public class Order {
private Integer id;
private String orderNo;
private String orderAddress;
private Double totalPrice;
private List<Product> productList;
}
服務(wù)層
package org.example.service;
import org.example.entity.Order;
public interface OrderService {
Order selectOnOrderById(Integer id);
}
package org.example.service.impl;
import org.example.entity.Order;
import org.example.entity.Product;
import org.example.service.OrderService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.http.ResponseEntity;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
import java.util.List;
@Service
public class OrderServiceImpl implements OrderService {
@Autowired
RestTemplate restTemplate;
@Override
public Order selectOnOrderById(Integer id) {
System.out.println("get order ");
return new Order(id, "order-001", "China", 22788D, selectProductListById(id));
}
private List<Product> selectProductListById(Integer id) {
ResponseEntity<List<Product>> response = restTemplate.exchange("http://service-provider/product/list",
HttpMethod.GET, null, new ParameterizedTypeReference<List<Product>>() {
});
System.out.println(response.getBody());
return response.getBody();
}
}
Controller層
package org.example.controller;
import org.example.entity.Order;
import org.example.service.OrderService;
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.RestController;
@RestController
@RequestMapping(value = "/order")
public class OrderController {
@Autowired
private OrderService orderService;
@RequestMapping(value = "/{id}")
public Order getOrder(@PathVariable("id") Integer id){
return orderService.selectOnOrderById(id);
}
}
啟動(dòng),注意RestTemplate要注冊(cè)為bean
package org.example;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@SpringBootApplication
public class ConsumerApp {
@Bean
@LoadBalanced
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApp.class, args);
}
}
訪問localhost:9090/order/1即可得到數(shù)據(jù)
其他還需要學(xué)習(xí):
使用Consul API或CLI工具來查詢注冊(cè)的服務(wù),了解如何發(fā)現(xiàn)其他服務(wù)。
健康檢查:
設(shè)置健康檢查,以確保注冊(cè)的服務(wù)保持健康狀態(tài)。
實(shí)驗(yàn)并了解Consul如何自動(dòng)處理不健康的服務(wù)。
分布式鍵值存儲(chǔ):
使用Consul的鍵值存儲(chǔ)功能,存儲(chǔ)和檢索配置數(shù)據(jù)或其他鍵值信息。
熟悉Consul的API和CLI命令,以便與鍵值存儲(chǔ)進(jìn)行交互。
安全和認(rèn)證:
學(xué)習(xí)如何配置Consul以實(shí)現(xiàn)安全的通信,例如使用TLS。
了解Consul的訪問控制和身份驗(yàn)證機(jī)制。
集成到實(shí)際應(yīng)用中:
將Consul集成到你的應(yīng)用架構(gòu)中,以實(shí)現(xiàn)服務(wù)發(fā)現(xiàn)和配置管理。
編寫腳本或使用現(xiàn)有工具,以自動(dòng)化Consul的配置和運(yùn)維任務(wù)。
學(xué)習(xí)資源:
閱讀Consul的官方文檔,這是學(xué)習(xí)的重要資源。
參與社區(qū)和論壇,與其他使用Consul的人交流經(jīng)驗(yàn)。
實(shí)踐項(xiàng)目:
探索更復(fù)雜的用例,以更深入地理解Consul的功能。
學(xué)習(xí)Consul可能需要一些時(shí)間,但掌握這些基本概念和技能將有助于你更好地管理分布式系統(tǒng)和微服務(wù)架構(gòu)中的服務(wù)發(fā)現(xiàn)和配置管理。不斷實(shí)踐和探索是提高你的Consul技能的關(guān)鍵。文章來源:http://www.zghlxwxcb.cn/news/detail-724061.html
學(xué)習(xí)視頻https://www.bilibili.com/video/BV1Ti4y1w7Um/?p=9&spm_id_from=333.337.top_right_bar_window_history.content.click
參考文檔:
http://www.hu-rong.com/article_list/61文章來源地址http://www.zghlxwxcb.cn/news/detail-724061.html
到了這里,關(guān)于微服務(wù)框架Consul--新手入門的文章就介紹完了。如果您還想了解更多內(nèi)容,請(qǐng)?jiān)谟疑辖撬阉鱐OY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!