zookeeper搭建服务自动注册与监控

来源:互联网 发布:易观智库 数据哪来的 编辑:程序博客网 时间:2024/05/17 23:31
package com.htsc.rpc.config;

import org.springframework.boot.context.properties.ConfigurationProperties;

import lombok.Data;

@Data
@ConfigurationProperties(prefix=RpcProperties.PREFIX)
public class RpcProperties {
    
    public static final String PREFIX="services.register";
    
    private String zookeeper;
    

}



package com.htsc.rpc.config;

import java.net.InetAddress;
import java.net.NetworkInterface;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import java.util.regex.Pattern;

import javax.annotation.PostConstruct;
import javax.annotation.PreDestroy;

import org.I0Itec.zkclient.ZkClient;
import org.I0Itec.zkclient.exception.ZkMarshallingError;
import org.I0Itec.zkclient.serialize.ZkSerializer;
import org.apache.commons.codec.Charsets;
import org.apache.log4j.Logger;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.context.embedded.EmbeddedServletContainerInitializedEvent;
import org.springframework.boot.context.properties.EnableConfigurationProperties;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.context.ApplicationListener;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.env.Environment;
import org.springframework.util.StringUtils;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.mvc.condition.PatternsRequestCondition;
import org.springframework.web.servlet.mvc.method.RequestMappingInfo;
import org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerMapping;

@EnableConfigurationProperties(RpcProperties.class)
@Configuration
public class RegisterConfig implements CommandLineRunner, ApplicationContextAware,
        ApplicationListener<EmbeddedServletContainerInitializedEvent> {

    private static final Logger logger = Logger.getLogger(RegisterConfig.class);

    private ApplicationContext applicationContext;

    private int serverPort;

    private final String root = "/zlcft/services";

    private String serverHost;

    @Autowired
    private RpcProperties rpcProperties;
    @Autowired
    private Environment env;

    private ZkClient zkClient;

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException
    {
        this.applicationContext = applicationContext;
    }

    @Override
    public void run(String... args) throws Exception
    {
        this.serverHost = getNetworkAddress();
        // 当前服务ip:sort
        if (serverHost == null || "".equals(serverHost) || serverPort == 0)
        {
            logger.info(RegisterConfigConstants.NO_FIND_SERVER_HOST);
            return;
        }
        try
        {
            RequestMappingHandlerMapping mapping = applicationContext.getBean(RequestMappingHandlerMapping.class);
            Map<RequestMappingInfo, HandlerMethod> map = mapping.getHandlerMethods();
            // 创建根节点
            String application = root;
            if (!zkClient.exists(application))
            {
                try
                {
                    zkClient.createPersistent(application, true);
                }
                catch (Exception e)
                {
                    logger.info(RegisterConfigConstants.NODE_NO_CREATE_SUCCESS);
                }
            }
            // 获取RequestMapping value
            for (Entry<RequestMappingInfo, HandlerMethod> entry : map.entrySet())
            {
                PatternsRequestCondition pattern = entry.getKey().getPatternsCondition();
                if (null != pattern)
                {
                    Set<String> sets = pattern.getPatterns();
                    if (null == sets || sets.size() == 0)
                    {
                        continue;
                    }
                    String subUrl = sets.toString().substring(1, sets.toString().length() - 1);
                    // 条件过滤无需注册的服务
                    if (null != subUrl && !"".equals(subUrl) && !subUrl.contains("error")
                            && !subUrl.contains("swagger-resources") && !subUrl.contains("v2")
                            && !subUrl.contains("cache"))
                    {
                        String[] urlArr = subUrl.substring(1).split("/");
                        if (null != urlArr && urlArr.length > 1)
                        {
                            // 类级别的RequestMapping value
                            StringBuffer rclassPath = new StringBuffer(urlArr[0]);
                            // 多层路径拼接
                            for (int i = 1; i < urlArr.length; i++)
                            {
                                Pattern pat = Pattern.compile("[0-9]*");
                                if (!pat.matcher(urlArr[i]).matches())
                                {
                                    rclassPath.append("_" + urlArr[i]);
                                    continue;
                                }
                                break;
                            }
                            String spath = rclassPath.toString();
                            String path = application + "/" + spath;
                            String iport = serverHost + ":" + serverPort;
                            // ip和port的全路径
                            String newNode = path + "/" + iport;
                            if (!zkClient.exists(path))
                            {
                                try
                                {
                                    zkClient.createPersistent(path);
                                    zkClient.createEphemeral(newNode);
                                }
                                catch (Exception e)
                                {
                                    logger.info(RegisterConfigConstants.NODE_NO_CREATE_SUCCESS);
                                }
                            }
                            else
                            {
                                List<String> childs = zkClient.getChildren(path);
                                if (!childs.contains(iport))
                                {
                                    try
                                    {
                                        zkClient.createEphemeral(newNode);
                                    }
                                    catch (Exception e)
                                    {
                                        logger.info(RegisterConfigConstants.NODE_NO_CREATE_SUCCESS);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        catch (Exception e)
        {
            logger.error(e.getMessage(), e);
        }
    }

    @PreDestroy
    public void destory()
    {
        zkClient.close();
    }

    @Override
    public void onApplicationEvent(EmbeddedServletContainerInitializedEvent event)
    {
        this.serverPort = event.getEmbeddedServletContainer().getPort();
    }

    @PostConstruct
    private void init()
    {
        // 启用默认配置
        String zookeeper = rpcProperties.getZookeeper();
        if (!StringUtils.isEmpty(zookeeper))
        {
            zkClient = new ZkClient(zookeeper);
            zkClient.setZkSerializer(new MyZkSerializer());
            return;
        }

        // 启用dubbo配置
        String address = env.getProperty("dubbo.registry.address");
        if (!StringUtils.isEmpty(address))
        {
            String[] strArr = address.split("backup=");
            String addr = null;
            if (strArr != null && strArr.length > 1)
            {
                addr = strArr[0].substring(12, strArr[0].length() - 1);
                zkClient = new ZkClient(addr);
                zkClient.setZkSerializer(new MyZkSerializer());
            }
        }
    }

    public String getNetworkAddress()
    {
        try
        {
            Enumeration<NetworkInterface> netInterfaces = NetworkInterface.getNetworkInterfaces();
            while (netInterfaces.hasMoreElements())
            {
                NetworkInterface netInterface = netInterfaces.nextElement();
                Enumeration<InetAddress> ips = netInterface.getInetAddresses();
                while (ips.hasMoreElements())
                {
                    InetAddress address = ips.nextElement();
                    if (!address.isSiteLocalAddress() && !address.isLoopbackAddress()
                            && address.getHostAddress().indexOf(":") == -1)
                    {
                        return address.getHostAddress();
                    }
                }
            }
        }
        catch (Exception e)
        {
            logger.info(RegisterConfigConstants.GET_IP_ERROR);
        }
        return null;
    }

    class MyZkSerializer implements ZkSerializer {
        public Object deserialize(byte[] bytes) throws ZkMarshallingError
        {
            return new String(bytes, Charsets.UTF_8);
        }

        public byte[] serialize(Object obj) throws ZkMarshallingError
        {
            return String.valueOf(obj).getBytes(Charsets.UTF_8);
        }
    }

}


原创粉丝点击