springcloud+zookeeper 的服务发现与服务集群的搭建方式

简介

内容来源:链接
这是Eureka的替代方案,因为Eureka没更新了。
这个方案的搭建过程和Eureka一样方便。
尤其是服务集群的搭建,非常适合动态水平扩展,我觉得这点比 Eureka 强,因为 Eureka 需要配置 defaultZone 来指明各个集群服务器的地址,但是 Zookeeper 这个方案不需要修改配置文件,只要 spring.application.name 相同就被认为是同一个服务,然后集群服务设置不同端口就行了。

环境搭建

  • 注意,客户端和服务端的搭建方式完全一样,没有任何不同。
  • zookeeper整合springboot
<properties>
    <maven.compiler.source>8maven.compiler.source>
    <maven.compiler.target>8maven.compiler.target>
    <spring.version>2.3.0.RELEASEspring.version>
properties>

<dependencyManagement>
    <dependencies>
        
        <dependency>
            <groupId>org.springframework.bootgroupId>
            <artifactId>spring-boot-dependenciesartifactId>
            <version>${spring.version}version>
            <type>pomtype>
            <scope>importscope>
        dependency>
        
        <dependency>
            <groupId>org.springframework.cloudgroupId>
            <artifactId>spring-cloud-dependenciesartifactId>
            <version>Hoxton.SR1version>
            <type>pomtype>
            <scope>importscope>
        dependency>
    dependencies>
dependencyManagement>


<dependencies>
    <dependency>
        <groupId>org.springframework.bootgroupId>
        <artifactId>spring-boot-starter-webartifactId>
    dependency>
    
    <dependency>
        <groupId>org.springframework.cloudgroupId>
        <artifactId>spring-cloud-starter-zookeeper-discoveryartifactId>
    dependency>
dependencies>
  • application.yml
    • 需要配置 zookeeper 的连接地址
#服务别名----注册zookeeper到注册中心名称
spring:
  application:
    # 应用名称(服务名称)
    name: cloud-provider-payment
  cloud:
    zookeeper:
      # zookeeper的连接地址,多节点用逗号隔开
      connect-string: 192.168.132.201:2181
  • 主启动类,类上加上下面这个注解
//该注解用于向使用consul或者zookeeper作为注册中心时注册服务
@EnableDiscoveryClient

可能出现的问题

org.apache.zookeeper.KeeperException$UnimplementedException: KeeperErrorCode = Unimplemented for
这个是由于使用的zookeeper版本过低导致的,可以升级zookeeper的版本,或者降低引入的引擎版本


<dependency>
    <groupId>org.springframework.cloudgroupId>
    <artifactId>spring-cloud-starter-zookeeper-discoveryartifactId>
    
    <exclusions>
        <exclusion>
            <groupId>org.apache.zookeepergroupId>
            <artifactId>zookeeperartifactId>
        exclusion>
    exclusions>
dependency>

<dependency>
    <groupId>org.apache.zookeepergroupId>
    <artifactId>zookeeperartifactId>
    <version>3.4.9version>
dependency>

服务中心的使用

节点信息的位置和含义

使用 zookeeper 客户端连接 zookeeper 会发现注册进去的服务变成了一个临时节点,连接的服务信息会被存储在 /services/{服务名}/{UUID} 节点下信息内容类似于下面这个

{
    "name": "cloud-provider-payment",
    "id": "ae024e43-703b-4edc-8a73-2cb7758fdb35",
    "address": "root",
    "port": 8084,
    "sslPort": null,
    "payload": {
        "@class": "org.springframework.cloud.zookeeper.discovery.ZookeeperInstance",
        "id": "application-1",
        "name": "cloud-provider-payment",
        "metadata": {}
    },
    "registrationTimeUTC": 1602687210606,
    "serviceType": "DYNAMIC",
    "uriSpec": {
        "parts": [
            {
                "value": "scheme",
                "variable": true
            },
            {
                "value": "://",
                "variable": false
            },
            {
                "value": "address",
                "variable": true
            },
            {
                "value": ":",
                "variable": false
            },
            {
                "value": "port",
                "variable": true
            }
        ]
    }
}

服务断连

  • 一旦service宕机,zookeeper不会立马下线服务的节点,而是等待一段时间,一段时间过后仍旧断连的话,zookeeper 会删除该服务的临时节点。等到服务重新上线后,Zookeeper会重新生成一个临时服务节点。

服务调用

  • 该功能让客户端和服务端都注册进 Zookeeper 中,客户端可以通过服务的项目名 + 接口名来调用到服务的接口
  • 需要使用RestTemplate
    • 可以配置负载均衡和请求头信息
package wu.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;

/**
 * @auther zzyy
 * @create 2020-02-19 15:20
 */
@Configuration
public class ApplicationContextConfig
{
    @Bean
    @LoadBalanced
    public RestTemplate getRestTemplate()
    {
        return new RestTemplate();
    }
}
  • 使用
package wu.controller;

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 org.springframework.web.client.RestTemplate;

@RestController
@RequestMapping
public class ServerController {
    @Autowired
    private RestTemplate restTemplate;
  	// 这里指明访问的服务项目名,对应spring.application.name
    public static final String INVOKE_URL = "http://cloud-provider-server";

    @GetMapping("/client")
    public String test(){
      	// 这里将直接被转发到服务端上,返回的数据就是服务返回的数据
        String result = restTemplate.getForObject(INVOKE_URL+"/server",String.class);
        return result;
    }
}

服务集群

  • 这里实现集群比较简单,比Eureka做的更方便。
  • 就是完全拷贝服务项目,然后只更改端口号,其他什么都不变即可
  • 因为 spring.application.name 是一致的,所以它们被 Zookeeper 认为是同一个服务,客户端可以通过相同的方式访问到,并且 RestTemplate 设置为负载均衡的话,可以平衡地访问两个服务。
  • 使用 Docker 把服务项目生成一个镜像,然后在启动多个暴露不同端口的容器,这样实现集群是非常方便的。

你可能感兴趣的:(Java,java,spring,cloud,服务发现,spring,boot,zookeeper)