Consul 服务注册和发现示例

了解如何基于,在注册表服务器上进行注册来创建Microservices,以及其他微服务(发现客户端)如何使用它来注册和发现服务以调用其API。Spring cloudHashiCorp Consul

我们将使用基于Spring Boot的Spring Cloud API。我们将使用Consul注册表服务器来构建服务注册表服务器和通用发现客户端,后者将自行注册并发现其他服务以调用REST API。

目录

概述
在本地工作站中配置Consul 
Student服务
School服务-Discovery Client 
演示
检查是否遇到任何错误的内容
摘要

总览

领事提供服务发现,配置管理,运行状况检查和键值存储等多种功能。今天,我们将专注于服务注册和发现部分。我们将开发以下组件来构建分布式生态系统,其中每个组件都相互依赖,但是它们之间的耦合非常松散,当然还有容错能力。

  • Consul Agent –在本地主机上运行,​​充当发现/注册服务器功能。
  • Student微服务 –将提供一些基于Student 实体的功能。这将是一个基于休息的服务,最重要的是它将是一个发现服务客户端,该客户端将与Consul Server / Agent对话以在服务注册表中注册自己。
  • School微服务–与Student服务的类型相同–唯一增加的功能是它将通过服务查找机制调用Student服务。我们不会使用Student服务的绝对URL与该服务进行交互。我们将使用Consul发现功能,并在调用该功能之前先使用它查找Student服务实例。

这是相同组件的整体组件交互图。

组件图

技术堆栈和运行时

  • Java 1.8
  • Eclipse IDE
  • 领事即服务注册服务器
  • Spring Cloud
  • Spring Boot
  • Spring休息
  • 马文

在本地工作站中配置领事

在开始练习之前,我们需要首先在localhost中下载,配置和运行consul代理。

  • 领事门户下载。根据操作系统选择特定的程序包。下载压缩文件后,我们需要将其解压缩到所需位置。
  • 在本地工作站中启动Consul Agent –我们已解压缩的Zip文件只有一个名为的exe文件consul.exe。我们将在此处启动命令提示符,并使用以下命令启动代理。
    consul agent -server -bootstrap-expect=1 -data-dir=consul-data -ui -bind=192.168.6.1

    确保输入正确的绑定地址,根据局域网设置的不同,绑定地址会有所不同。做一个ipconfig在命令提示符知道你的IPv4地址,并在这里使用它。

    ipconfig命令
    代理启动命令日志
  • 测试Consul Server是否正在运行 – Consul在默认端口上运行,并且代理成功启动后,浏览http:// localhost:8500 / ui,您应该看到一个控制台屏幕,如–
    领事控制台–未注册服务

因此,我们已经在本地计算机中配置了consul,并且consul代理已成功运行。现在,我们需要创建客户端并测试服务注册表和发现部分。

Student服务

请按照以下步骤创建和运行Student服务。这将是一个发现客户端,将其注册到现在已经在我们的计算机中运行的领事服务。

创建Student项目

从带有四个依赖项的初始化程序门户创建一个Spring Boot项目,即

  • Actuator
  • 网页
  • 其余资料库
  • 领事发现

给出其他Maven GAV坐标并下载项目。

Student服务项目生成

将项目解压缩并将其作为现有的maven项目导入Eclipse。

现在@org.springframework.cloud.client.discovery.EnableDiscoveryClient,在src文件夹中存在的Spring Boot应用程序类上添加注解。有了此注解,此工件将像Spring Discovery客户端一样发挥作用,并在连接到此服务的领事服务器中注册自己。

package com.example.howtodoinjava.springcloudconsulstudent;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
@EnableDiscoveryClient
public class SpringCloudConsulStudentApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsulStudentApplication.class, args);
    }
}

服务配置

打开application.properties并添加以下属性

server.port=9098
spring.application.name: student-service
management.security.enabled=false

这是每个属性的详细信息–

  • server.port=9098–将在默认的9098端口中启动服务。
  • spring.application.name: student-service–将使用student-service标签在领事服务器中注册自己,其他服务也将使用此名称本身查找该服务。
  • management.security.enabled=false –此练习实际上不是必需的,但是它将在 Actuator 模块提供的管理端点中禁用Spring安全性。

添加REST API

现在添加一个RestController并公开一个休息点,以获取特定School的所有Student详细信息。在这里,我们公开/getStudentDetailsForSchool/{schoolname}了服务于业务目的的端点。为简单起见,我们正在对Student详细信息进行硬编码。

package com.example.howtodoinjava.springcloudconsulstudent.controller;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
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.example.howtodoinjava.springcloudconsulstudent.domain.Student;
@RestController
public class StudentServiceController {
    private static Map<String, List<Student>> schooDB = new HashMap<String, List<Student>>();
    static {
        schooDB = new HashMap<String, List<Student>>();
        List<Student> lst = new ArrayList<Student>();
        Student std = new Student("Sajal""Class IV");
        lst.add(std);
        std = new Student("Lokesh""Class V");
        lst.add(std);
        schooDB.put("abcschool", lst);
        lst = new ArrayList<Student>();
        std = new Student("Kajal""Class III");
        lst.add(std);
        std = new Student("Sukesh""Class VI");
        lst.add(std);
        schooDB.put("xyzschool", lst);
    }
    @RequestMapping(value = "/getStudentDetailsForSchool/{schoolname}", method = RequestMethod.GET)
    public List<Student> getStudents(@PathVariable String schoolname) {
        System.out.println("Getting Student details for " + schoolname);
        List<Student> studentList = schooDB.get(schoolname);
        if (studentList == null) {
            studentList = new ArrayList<Student>();
            Student std = new Student("Not Found""N/A");
            studentList.add(std);
        }
        return studentList;
    }
}

Student.java模型

package com.example.howtodoinjava.springcloudconsulstudent.domain;
public class Student {
    private String name;
    private String className;
    
    public Student(String name, String className) {
        super();
        this.name = name;
        this.className = className;
    }
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }
    public String getClassName() {
        return className;
    }
    public void setClassName(String className) {
        this.className = className;
    }
}

验证Student服务

作为spring boot应用程序启动该项目。现在,确认此服务已在Consul服务器中自动注册。转到Consul Agent控制台并刷新页面。现在,如果一切顺利,我们将student-service在Consul Agent控制台中看到一个条目。

领事控制台Student服务已注册

这表明Consul服务器和客户端都相互了解,这是Consul服务器和Student服务之间发生的一种自动注册和发现。

现在,我们将验证/getStudentDetailsForSchool/{schoolname}端点是否已启动并正在运行。转到浏览器并转到http:// localhost:9098 / getStudentDetailsForSchool / abcschool,它将为特定Schoolabcschool提供Student详细信息。

Student服务响应

School服务–发现客户

现在,我们将创建School服务,该服务将在领事服务器中进行注册-它将发现并调用没有硬编码URL路径的Student服务。

请按照相同的步骤创建和运行School服务。这将是一个发现客户端,将其注册到现在已经在我们的计算机中运行的领事服务。

它将内部调用已开发的Student服务,并将使用领事服务发现功能来发现Student实例。

创建School项目

从带有四个依赖项的初始化程序门户创建一个Spring Boot项目,即

  • Actuator
  • 网页
  • 其余资料库
  • 领事发现

给出其他Maven GAV坐标并下载项目。

School一代

将项目解压缩并将其作为现有的maven项目导入Eclipse。

现在@org.springframework.cloud.client.discovery.EnableDiscoveryClient,在src文件夹中存在的Spring Boot应用程序类上添加注解。有了此注解,此工件将像Spring Discovery客户端一样发挥作用,并在连接到此服务的领事服务器中注册自己。

package com.example.howtodoinjava.springcloudconsulschool;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@EnableDiscoveryClient
@SpringBootApplication
public class SpringCloudConsulSchoolApplication {
    public static void main(String[] args) {
        SpringApplication.run(SpringCloudConsulSchoolApplication.class, args);
    }
}

服务配置

打开application.properties并添加以下属性

server.port=8098
spring.application.name: school-service
management.security.enabled=false

这是每个属性的详细信息–

  • server.port=8098–将在默认的8098端口中启动服务
  • spring.application.name: school-service–将使用school-service标签在领事服务器中注册自己。
  • management.security.enabled=false –将在 Actuator 模块提供的管理端点中禁用Spring安全性。

添加使用Student服务的REST API的REST API

现在添加一个RestController并公开一个休息点以获取School详细信息。该端点将使用带有应用程序名称的服务发现样式URL,而不是带有host:port的完整URL约定。

SchoolServiceController.java

package com.example.howtodoinjava.springcloudconsulschool.controller;
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.example.howtodoinjava.springcloudconsulschool.delegate.StudentServiceDelegate;
@RestController
public class SchoolServiceController {
    
    @Autowired
    StudentServiceDelegate studentServiceDelegate;
    @RequestMapping(value = "/getSchoolDetails/{schoolname}", method = RequestMethod.GET)
    public String getStudents(@PathVariable String schoolname)
    {
        System.out.println("Going to call student service to get data!");
        return studentServiceDelegate.callStudentServiceAndGetData(schoolname);
    }
}

StudentServiceDelegate.java

package com.example.howtodoinjava.springcloudconsulschool.delegate;
import java.util.Date;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.core.ParameterizedTypeReference;
import org.springframework.http.HttpMethod;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;
@Service
public class StudentServiceDelegate
{
    @Autowired
    RestTemplate restTemplate;
    
    public String callStudentServiceAndGetData(String schoolname)
    {
        System.out.println("Consul Demo - Getting School details for " + schoolname);
        String response = restTemplate.exchange("http://student-service/getStudentDetailsForSchool/{schoolname}",                                       HttpMethod.GET, nullnew ParameterizedTypeReference<String>() {},                                                schoolname).getBody();
        
        System.out.println("Response Received as " + response + " -  " + new Date());
        return "School Name -  " + schoolname + " :::  Student Details " + response + " -  " + new Date();
    }
    
    @Bean
    @LoadBalanced
    public RestTemplate restTemplate() {
        return new RestTemplate();
    }
}

看上面的代码。在中StudentServiceDelegate,我们习惯于RestTemplate调用Student服务,并将Student服务的URL用作。http://student-service/getStudentDetailsForSchool/{schoolname}

这样,我们可以摆脱特定的服务配置,并且可以赋予服务查找consul此处提供的服务器和其余模板的责任。@LoadBalanced如果多个实例正在为同一服务运行,我们也可以在此处应用负载平衡(请参阅注解)。

Demo

逐步执行以下步骤以了解整个过程–

  • 检查Consul Agent是否仍在运行 –打开浏览器并浏览http:// localhost:8500 / ui。它应该显示如上所述的领事控制台。
  • 检查Student服务已在运行 –从领事管理页面和浏览器中检查Student服务已启动并正在运行。如果没有启动该服务,并验证它已在领事服务器中注册。
  • 启动并检查School服务 –从命令提示符启动School服务,并检查它是否已在领事服务器中注册。
  • 打开浏览器并使用URL http:// localhost:8098 // getSchoolDetails / abcschool测试SchoolREST服务 。它将给出以下响应,并将使用领事服务在内部调用Student服务。
    School服务回应
  • 也可以尝试通过更改端口来启动多实例Student服务。这些也将在领事中注册,并且由于我们在中使用注解,因此负载平衡也将在内部完成。检查相应的Student服务控制台,以验证在多实例方案中调用了哪个实例。java -jar "-Dserver.port=9099 target\spring-cloud-consul-student-0.0.1-SNAPSHOT.jar@LoadBalancedRestTemplate一旦我们注册了多个服务和多个实例,领事服务器的外观将如此。
    领事所有服务正在运行

检查是否遇到任何错误的事情

  • 注解@EnableDiscoveryClient和Consul代理运行是应用程序生态系统的核心。没有这两个东西将根本无法工作。
  • 确保在开始School服务,Student服务,领事服务器时已运行代理程序,否则可能要花一些时间进行注册,并且在测试时可能会造成混乱。

摘要

我们看到了如何轻松高效地部署领事服务注册表和发现服务器以及客户端。Spring框架在内部维护着很多东西。在这里,我们仅使用几个注解和非常少的配置即可快速完成所有操作。

这就是为微服务创建spring consul服务器和服务注册。

如果您在执行本文时遇到任何困难,请添加评论。我们将很乐意调查这个问题。

saigon has written 1445 articles

Leave a Reply