consul-02.consul服务注册实现(java)

一,续

在上一篇文章中简单介绍了下consul和集群环境搭建,点我查看上一篇文章。
本篇中将介绍怎么将服务注册至consul集群中,并形成一个公共jar包,在springmvc或者springboot应用启动时将服务注册至consul集群中,应用退出时将服务从consul集群中移除。

二,实现思路

1.consul集群如何利用

这里将利用consul的健康检查的特性来保证我们服务消费方发现的服务是健康可用的。
服务提供方一般是我们的应用程序,比如会员服务,订单服务之类的,服务消费方一般是我们的网关。
比如会员服务有三台机器,将三台机器的ip和port分别注册至consul集群中,当会员服务的某台机器挂掉之后,consul集群中的健康检查就会将该服务标记为严重,网关向consul集群中获取健康的服务列表时,该机器提供的服务将不能被发现,
网关转发请求时自然就不会把请求转发到挂掉的那台机器了。
另外利用服务注册时提供的tag,我们可以利用tag做版本管理,发现服务时可以根据tag来查询。
还有一点就是,我们可以利用该思路来做灰度发布,如果网关做的比较完善的话,我只要保证每个服务有一台机器正常提供服务,整个系统就能一直正常运行,能做到随时增加和减少某个服务的机器。

坑:当你向集群中的某个节点注册服务时,该节点不会向其他节点扩散该服务信息,该节点挂掉后,该服务将不能被发现。我的解决办法比较暴力,将该服务信息向集群中的所有节点注册,服务发现时再将重复的服务信息,即ip+端口+版本一致的话,即认为是重复的服务,只保留一条该服务信息。

2.技术方面

技术方面主要是分别实现spring的InitializingBean,DisposableBean两个接口来达到应用程序启动时执行注册,应用程序退出时销毁服务。

三,实现spring应用程序注册至consul集群公共jar包

1.代码包结构,有以下几个类

  • com.sdk.consul.consts.ConsulConsts.java
    因为我们的配置文件properties每个环境只有一份,而且同一服务会在多台服务器上部署,每台服务器的ip和端口不一样,所以为了发布的时候不修改properties文件,故一般会在jvm启动参数中配置当前服务的ip和端口,这个文件定义的就是这两个启动参数的名字。
  • com.sdk.consul.exception.ConsulServiceException.java
    异常类,不多说了。
  • com.sdk.consul.utils.Md5Utils.java
    对应用服务ip+端口加密生成serviceid,保证服务器ip和端口不变,生成的servcieid也不变
  • com.sdk.consul.utils.ServerUtils.java
    通过java代码获取当前服务器ip和web服务器(如tomcat)的运行端口,多网卡下会有问题,因此这是获取应用服务ip和端口的最后一个选项。
  • com.sdk.consul.utils.StringUtils.java
    处理字符串的类,不多帅。
  • com.sdk.consul.ConsulConfig.java
    服务注册入口,spring mvc将此类在xml中定义成bean即可,类似下面这样:
    <bean class="com.sdk.consul.ConsulConfig"></bean>
    springboot在启动入口类中@Import(ConsulConfig.class)
  • com.sdk.consul.ConsulProperty.java
    properties配置文件配置信息类
  • com.sdk.consul.RegisterService.java
    服务操作类,提供注册和销毁服务等方法。

2.jar包依赖

  • pom依赖以下jar包
<dependencies>
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>slf4j-api</artifactId>
        <version>1.7.5</version>
    </dependency>
    <dependency>
        <groupId>com.ecwid.consul</groupId>
        <artifactId>consul-api</artifactId>
        <version>1.3.0</version>
    </dependency>
    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-context</artifactId>
        <version>3.2.9.RELEASE</version>
        <scope>compile</scope>
    </dependency>
</dependencies>

3.类具体代码

  • com.sdk.consul.consts.ConsulConsts.java
package com.sdk.consul.consts;

public class ConsulConsts {
   

    /** JVM启动参数名称-服务暴露地址 */
    public static final String CONSUL_SERVICE_URL = "CONSUL_SERVICE_URL";

    /**VM启动参数名称-服务暴露端口*/
    public static final String CONSUL_SERVICE_PORT = "CONSUL_SERVICE_PORT";
}
  • com.sdk.consul.exception.ConsulServiceException.java
package com.sdk.consul.exception;

/**
 * Consul服务注册异常类
 */
public class ConsulServiceException extends RuntimeException{
   

    public ConsulServiceException() {
        super();
    }

    public ConsulServiceException(final String message) {
        super(message);
    }

    public ConsulServiceException(final String message, final Throwable cause) {
        super(message, cause);
    }

}
  • com.sdk.consul.utils.Md5Utils.java
package com.sdk.consul.util;

import com.sdk.consul.exception.ConsulServiceException;
import java.security.MessageDigest;
import java.security.NoSuchAlgorithmException;

public class Md5Utils {
   

    /**
     * MD5加密
     * @param source 加密前字符串
     * @return
     * @throws ConsulServiceException
     * @throws NoSuchAlgorithmException
     */
    public static String encrypt(String source) throws ConsulServiceException,NoSuchAlgorithmException {
        if(StringUtils.isEmpty(source)){
            throw new ConsulServiceException("Please input a not blank value to encrypt md5.");
        }
        MessageDigest md5 = MessageDigest.getInstance("MD5");
        byte[] md5Bytes = md5.digest(source.getBytes());
        StringBuffer hexValue = new StringBuffer();
        for (int i = 0; i < md5Bytes.length; i++) {
            int val = ((int
  • 0
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值