用ZooKeeper做為注冊中心搭建基於Spring Cloud實現服務注冊與發現


前提:

先安裝好ZooKeeper的環境,搭建參考:http://www.cnblogs.com/EasonJim/p/7482961.html

說明:

可以再簡單的理解為有兩方協作,一個是服務提供這,另一個是服務消費者。

搭建實例:

說明:基於Maven的模塊工程

父工程POM:

<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/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <groupId>com.jsoft.testzookeeper</groupId>
    <artifactId>zookeeperdemo</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <packaging>pom</packaging>
    <name>ZooKeeperDemo</name>
    <description>This is ZookKeeperDemo</description>
    
    <parent>
        <groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>1.4.5.RELEASE</version>
    </parent>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
        <java.version>1.8</java.version>
    </properties>

    <dependencies>
        <!-- 健康監控 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
        <!-- 斷路器 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-hystrix</artifactId>
        </dependency>
        <!-- 負載均衡 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-ribbon</artifactId>
        </dependency>
        <!-- ZK依賴 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-zookeeper-discovery</artifactId>
        </dependency>
        <!-- Web支持 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>    
        <!-- 測試 -->
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <scope>test</scope>
        </dependency>    
    </dependencies>

    <dependencyManagement>
        <dependencies>
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>Camden.SR7</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            
            <dependency>
                <groupId>junit</groupId>
                <artifactId>junit</artifactId>
                <version>3.8.1</version>
                <scope>test</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>    
    
    <modules>
        <module>zookeeperservice</module>
        <module>zookeeperclient</module>
    </modules>
</project>

服務提供者POM:

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jsoft.testzookeeper</groupId>
        <artifactId>zookeeperdemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.jsoft.testzookeeper</groupId>
    <artifactId>zookeeperservice</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>zookeeperservice</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        
    </dependencies>
</project>

application.properties:

server.port=8800
spring.application.name=/service-zookeeper
spring.cloud.zookeeper.discovery.root=/spring-cloud-service
spring.cloud.zookeeper.connect-string=localhost:2181

說明:定義端口,應用的名稱,服務在ZK的路徑,ZK的服務器地址,其中ZK的服務器地址可以有多個,用逗號隔開。

HelloController:

服務接口

package com.jsoft.testzookeeper.service.controller;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class HelloController {

    private static final Logger log = LoggerFactory.getLogger(HelloController.class);

    @RequestMapping(value = "/hello", method = RequestMethod.GET)
    public String sayHello(@RequestParam(name = "name") String name) {
        log.info("param:name->{}", name);
        return "hello: " + name;
    }
}

App:

程序入口

package com.jsoft.testzookeeper.service;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

@SpringBootApplication
@EnableDiscoveryClient
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class, args);
    }
}

說明:其中要@EnableDiscoveryClient標注為服務發現注解。

服務消費者POM:

<?xml version="1.0"?>
<project
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"
    xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
    <modelVersion>4.0.0</modelVersion>
    <parent>
        <groupId>com.jsoft.testzookeeper</groupId>
        <artifactId>zookeeperdemo</artifactId>
        <version>0.0.1-SNAPSHOT</version>
    </parent>
    <groupId>com.jsoft.testzookeeper</groupId>
    <artifactId>zookeeperclient</artifactId>
    <version>0.0.1-SNAPSHOT</version>
    <name>zookeeperclient</name>
    <url>http://maven.apache.org</url>
    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
    </properties>
    <dependencies>
        <!-- Feign客戶端 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-feign</artifactId>
        </dependency>
    </dependencies>
</project>

說明:由於使用了Feign客戶端,所以引入Feign依賴。

application.properties:

server.port=8810
spring.application.name=/client-zookeeper
spring.cloud.zookeeper.discovery.register=false
spring.cloud.zookeeper.discovery.root=/spring-cloud-service
spring.cloud.zookeeper.connect-string=localhost:2181
spring.cloud.zookeeper.dependencies.service-zookeeper.required=true
spring.cloud.zookeeper.dependencies.service-zookeeper.path=/service-zookeeper
spring.cloud.zookeeper.dependencies.service-zookeeper.loadBalancerType=ROUND_ROBIN

說明:由於服務提供者的應用名使用了斜杠,所以必須采用依賴關系spring.cloud.zookeeper.dependencies進行別名的選擇,注意,使用了這個之后要引入actuator健康監控組件,不然調用時會報錯。

App:

程序入口

package com.jsoft.testzookeeper.client;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;

@SpringBootApplication
@EnableDiscoveryClient
@EnableCircuitBreaker
@EnableFeignClients
public class App 
{
    public static void main( String[] args )
    {
        SpringApplication.run(App.class,args);
    }
}

說明:@EnableCircuitBreaker為斷路器的支持,@EnableFeignClients為Feign客戶端的支持。

Client的實現:

主要有兩種,基於RestTemplate和Feign

RestTemplate

package com.jsoft.testzookeeper.client.service;

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.client.RestTemplate;

@Service
public class HelloService {

    @Autowired
    private RestTemplate restTemplate;

    @HystrixCommand(fallbackMethod = "sayHelloFallback")
    public String sayHello(String name) {
        return restTemplate.getForEntity("http://service-zookeeper/hello?name=" + name, String.class).getBody();
    }

    private String sayHelloFallback(String name) {
        return "service error";
    }
}

說明:@HystrixCommand為斷路器寫法。

Feign

package com.jsoft.testzookeeper.client.service;

import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;

import com.jsoft.testzookeeper.client.service.fallback.FeignFallback;

@FeignClient(value = "service-zookeeper", fallback = FeignFallback.class)
public interface ServiceFeign {

    @RequestMapping(value = "/hello")
    String sayHello(@RequestParam(name = "name") String name);
}

說明:fallback為斷路器回調。

消費服務:

package com.jsoft.testzookeeper.client.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;

import com.jsoft.testzookeeper.client.service.HelloService;
import com.jsoft.testzookeeper.client.service.ServiceFeign;

@RestController
public class HelloController {

    @Autowired
    private HelloService helloService;

    @Autowired
    private ServiceFeign serviceFeign;

    @RequestMapping(value = "hello")
    public String hello(@RequestParam String name) {
        return helloService.sayHello(name);
    }

    @RequestMapping(value = "hello2")
    public String hello2(@RequestParam String name) {
        return serviceFeign.sayHello(name);
    }
}

總結:

Spring Cloud在服務發現和注冊上其實很多坑,上面展示的只是核心代碼,最全的還是參考例子代碼進行調試。

 

Maven示例:

https://github.com/easonjim/spring-cloud-demo/tree/master/ZooKeeper

 

參考:

http://theseus.iteye.com/blog/2366237

http://www.cnblogs.com/skyblog/p/5133752.html

http://blog.csdn.net/mn960mn/article/details/51803703

http://www.jianshu.com/p/775c363d0fda


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM