springcloud学习笔记

1. 服务的注册与发现(Eureka)

1、spring cloud简介

spring cloud 为开发人员提供了快速构建分布式系统的一些工具,包括配置管理、服务发现、断路器、路由、微代理、事件总线、全局锁、决策竞选、分布式会话等等。它运行环境简单,能够在开发人员的电脑上跑。java

2、建立服务注册中心

在这里,咱们须要用的的组件上Spring Cloud Netflix的Eureka ,eureka是一个服务注册和发现模块。git

开发环境:eclipse luna4.四、jdk1.八、maven3.2.3github

1eureka-server工程web

Pom.xmlspring

<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">sql

  <modelVersion>4.0.0</modelVersion>apache

  <groupId>com.forezp</groupId>bootstrap

  <artifactId>eureka-server</artifactId>后端

  <version>0.0.1-SNAPSHOT</version>api

 

  <parent>

       <groupId>org.springframework.boot</groupId>

       <artifactId>spring-boot-starter-parent</artifactId>

       <version>1.5.2.RELEASE</version>

       <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

           <artifactId>spring-cloud-starter-eureka-server</artifactId>

       </dependency>

 

       <dependency>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-test</artifactId>

           <scope>test</scope>

       </dependency>

    </dependencies>

 

    <dependencyManagement>

       <dependencies>

           <dependency>

              <groupId>org.springframework.cloud</groupId>

              <artifactId>spring-cloud-dependencies</artifactId>

              <version>Dalston.RC1</version>

              <type>pom</type>

              <scope>import</scope>

           </dependency>

       </dependencies>

    </dependencyManagement>

 

    <build>

       <plugins>

           <plugin>

              <groupId>org.springframework.boot</groupId>

              <artifactId>spring-boot-maven-plugin</artifactId>

           </plugin>

       </plugins>

    </build>

 

    <repositories>

       <repository>

           <id>spring-milestones</id>

           <name>Spring Milestones</name>

           <url>https://repo.spring.io/milestone</url>

           <snapshots>

              <enabled>false</enabled>

           </snapshots>

       </repository>

    </repositories>

 

</project>

 

2 启动一个服务注册中心,只须要一个注解@EnableEurekaServer,这个注解须要在springboot工程的启动application类上加:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

 

@EnableEurekaServer

@SpringBootApplication

public class EurekaServerApplication {

 

         public static void main(String[] args) {

                   SpringApplication.run(EurekaServerApplication.class, args);

         }

}

 

3.eureka是一个高可用的组件,它没有后端缓存,每个实例注册以后须要向注册中心发送心跳(所以能够在内存中完成),在默认状况下erureka server也是一个eureka client ,必需要指定一个 server。eureka server的配置文件appication.yml,在resources中建立

server:

  port: 8761

 

eureka:

  instance:

    hostname: localhost

  client:

    registerWithEureka: false

    fetchRegistry: false

    serviceUrl:

      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

4.eureka server 是有界面的,启动工程,打开浏览器访问: 
http://localhost:8761 ,界面以下

 

3、建立一个服务提供者 (eureka client)

当client向server注册时,它会提供一些元数据,例如主机和端口,URL,主页等。Eureka server 从每一个client实例接收心跳消息。 若是心跳超时,则一般将该实例从注册server中删除。

1.Pom.xml

<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.forezp</groupId>

  <artifactId>service-hi</artifactId>

  <version>0.0.1-SNAPSHOT</version>

 

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

  1. 经过注解@EnableEurekaClient 代表本身是一个eurekaclient.

package com.forezp;

 

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestParam;

import org.springframework.web.bind.annotation.RestController;

 

@SpringBootApplication

@EnableEurekaClient

@RestController

public class ServiceHiApplication {

 

    public static void main(String[] args) {

       SpringApplication.run(ServiceHiApplication.class, args);

    }

 

    @Value("${server.port}")

    String port;

    @RequestMapping("/hi")

    public String home(@RequestParam String name) {

       return "hi "+name+",i am from port:" +port;

    }

 

}

 

  1. 仅仅@EnableEurekaClient是不够的,还须要在配置文件中注明本身的服务注册中心的地址,application.yml配置文件以下:

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka/

server:

  port: 8762

spring:

  application:

    name: service-hi

须要指明spring.application.name,这个很重要,这在之后的服务与服务之间相互调用通常都是根据这个name 。 
4.启动工程,打开http://localhost:8761 ,即eureka server 的网址:

 

你会发现一个服务已经注册在服务中了,服务名为SERVICE-HI ,端口为8762

这时打开 http://localhost:8762/hi?name=forezp ,你会在浏览器上看到 :

hi forezp,i am from port:8762

2. 服务消费者(rest+ribbon)

1、ribbon简介

ribbon是一个负载均衡客户端,能够很好的控制htt和tcp的一些行为。Feign默认集成了ribbon。

ribbon 已经默认实现了这些配置bean:

  • IClientConfig ribbonClientConfig: DefaultClientConfigImpl
  • IRule ribbonRule: ZoneAvoidanceRule
  • IPing ribbonPing: NoOpPing
  • ServerList ribbonServerList: ConfigurationBasedServerList
  • ServerListFilter ribbonServerListFilter: ZonePreferenceServerListFilter
  • ILoadBalancer ribbonLoadBalancer: ZoneAwareLoadBalancer

2、准备工做

这一篇文章基于上一篇文章的工程,启动eureka-server 工程;启动service-hi工程,它的端口为8762;将service-hi的配置文件的端口改成8763,并启动,这时你会发现:service-hi在eureka-server注册了2个实例,这就至关于一个小的集群。访问localhost:8761如图所示:

 

3、建一个服务消费者

项目结构如图

 

从新新建一个spring-boot工程,取名为:service-ribbon; 
在它的pom.xml文件分别引入起步依赖spring-cloud-starter-eureka、spring-cloud-starter-ribbon、spring-boot-starter-web,代码以下:

<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.forezp</groupId>

  <artifactId>service-ribbon</artifactId>

  <version>0.0.1-SNAPSHOT</version>

 

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-ribbon</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

在工程的配置文件指定服务的注册中心地址为http://localhost:8761/eureka/,程序名称为 service-ribbon,程序端口为8764。配置文件application.yml以下:

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka/

server:

  port: 8764

spring:

  application:

    name: service-ribbon

在工程的启动类中,经过@EnableDiscoveryClient向服务中心注册;而且向程序的ioc注入一个bean: restTemplate;并经过@LoadBalanced注解代表这个restRemplate开启负载均衡的功能。

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

 

@SpringBootApplication

@EnableDiscoveryClient

public class ServiceRibbonApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ServiceRibbonApplication.class, args);

    }

 

    @Bean

    @LoadBalanced

    RestTemplate restTemplate() {

        return new RestTemplate();

    }

 

}

写一个测试类HelloService,经过以前注入ioc容器的restTemplate来消费service-hi服务的“/hi”接口,在这里咱们直接用的程序名替代了具体的url地址,在ribbon中它会根据服务名来选择具体的服务实例,根据服务实例在请求的时候会用具体的url替换掉服务名,代码以下:

package com.forezp.service;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

 

 

@Service

public class HelloService {

 

    @Autowired

    RestTemplate restTemplate;

 

    public String hiService(String name) {

        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);

    }

 

}

写一个controller,在controller中用调用HelloService 的方法,代码以下:

package com.forezp.web;

 

import com.forezp.service.HelloService;

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;

 

 

@RestController

public class HelloControler {

@Autowired

    HelloService helloService;

 

    @RequestMapping(value = "/hi")

    public String hi(@RequestParam String name){

        return helloService.hiService(name);

    }

}

在浏览器上屡次访问http://localhost:8764/hi?name=forezp,浏览器交替显示:

hi forezp,i am from port:8762

hi forezp,i am from port:8763

3.服务消费者(Feign)

1、Feign简介

Feign是一个声明式的伪Http客户端,它使得写Http客户端变得更简单。使用Feign,只须要建立一个接口并注解。它具备可插拔的注解特性,可以使用Feign 注解和JAX-RS注解。Feign支持可插拔的编码器和解码器。Feign默认集成了Ribbon,并和Eureka结合,默认实现了负载均衡的效果。

简而言之:

  • Feign 采用的是基于接口的注解
  • Feign 整合了ribbon

2、准备工做

继续用上一节的工程, 启动eureka-server,端口为8761; 启动service-hi 两次,端口分别为8762 、8763.

3、建立一个feign的服务

新建一个spring-boot工程,取名为serice-feign,在它的pom文件引入Feign的起步依赖spring-cloud-starter-feign、Eureka的起步依赖spring-cloud-starter-eureka、Web的起步依赖spring-boot-starter-web,代码以下:

<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.forezp</groupId>

  <artifactId>service-feign</artifactId>

  <version>0.0.1-SNAPSHOT</version>

 

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-feign</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

在工程的配置文件application.yml文件,指定程序名为service-feign,端口号为8765,服务注册地址为http://localhost:8761/eureka/ ,代码以下:

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka/

server:

  port: 8765

spring:

  application:

    name: service-feign

在程序的启动类ServiceFeignApplication ,加上@EnableFeignClients注解开启Feign的功能:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.netflix.feign.EnableFeignClients;

 

@SpringBootApplication

@EnableDiscoveryClient

@EnableFeignClients

public class ServiceFeignApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ServiceFeignApplication.class, args);

    }

}

定义一个feign接口,经过@ FeignClient(“服务名”),来指定调用哪一个服务。好比在代码中调用了service-hi服务的“/hi”接口,代码以下:

package com.forezp.service;

 

import org.springframework.cloud.netflix.feign.FeignClient;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RequestMethod;

import org.springframework.web.bind.annotation.RequestParam;

 

@FeignClient(value = "service-hi")

public interface SchedualServiceHi {

    @RequestMapping(value = "/hi",method = RequestMethod.GET)

    String sayHiFromClientOne(@RequestParam(value = "name") String name);

}

启动程序,屡次访问http://localhost:8765/hi?name=forezp,浏览器交替显示:

hi forezp,i am from port:8762

hi forezp,i am from port:8763

 

4.断路器(Hystrix)

在微服务架构中,根据业务来拆分红一个个的服务,服务与服务之间能够相互调用(RPC),在Spring Cloud能够用RestTemplate+Ribbon和Feign来调用。为了保证其高可用,单个服务一般会集群部署。因为网络缘由或者自身的缘由,服务并不能保证100%可用,若是单个服务出现问题,调用这个服务就会出现线程阻塞,此时如有大量的请求涌入,Servlet容器的线程资源会被消耗完毕,致使服务瘫痪。服务与服务之间的依赖性,故障会传播,会对整个微服务系统形成灾难性的严重后果,这就是服务故障的“雪崩”效应。

为了解决这个问题,业界提出了断路器模型。

1、断路器简介

Netflix开源了Hystrix组件,实现了断路器模式,SpringCloud对这一组件进行了整合。 在微服务架构中,一个请求须要调用多个服务是很是常见的,以下图:

 

较底层的服务若是出现故障,会致使连锁故障。当对特定的服务的调用的不可用达到一个阀值(Hystric 是5秒20次) 断路器将会被打开。

 

断路打开后,可用避免连锁故障,fallback方法能够直接返回一个固定值。

2、准备工做

这篇文章基于上一篇文章的工程,首先启动上一篇文章的工程,启动eureka-server 工程;启动service-hi工程,它的端口为8762。

3、在ribbon使用断路器

改造serice-ribbon 工程的代码,首先在pox.xml文件中加入spring-cloud-starter-hystrix的起步依赖:

<dependency>
<groupId></groupId>   org.springframework.cloud
<artifactId></artifactId>   spring-cloud-starter-hystrix
</dependency>

在程序的启动类ServiceRibbonApplication 加@EnableHystrix注解开启Hystrix:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.client.discovery.EnableDiscoveryClient;

import org.springframework.cloud.client.loadbalancer.LoadBalanced;

import org.springframework.cloud.netflix.hystrix.EnableHystrix;

import org.springframework.context.annotation.Bean;

import org.springframework.web.client.RestTemplate;

 

@SpringBootApplication

@EnableDiscoveryClient

@EnableHystrix

public class ServiceRibbonApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ServiceRibbonApplication.class, args);

    }

 

    @Bean

    @LoadBalanced

    RestTemplate restTemplate() {

        return new RestTemplate();

    }

}

 

改造HelloService类,在hiService方法上加上@HystrixCommand注解。该注解对该方法建立了熔断器的功能,并指定了fallbackMethod熔断方法,熔断方法直接返回了一个字符串,字符串为”hi,”+name+”,sorry,error!”,代码以下:

package com.forezp.service;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.stereotype.Service;

import org.springframework.web.client.RestTemplate;

 

import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;

 

 

@Service

public class HelloService {

 

    @Autowired

    RestTemplate restTemplate;

 

    @HystrixCommand(fallbackMethod = "hiError")

    public String hiService(String name) {

        return restTemplate.getForObject("http://SERVICE-HI/hi?name="+name,String.class);

    }

 

    public String hiError(String name) {

        return "hi,"+name+",sorry,error!";

    }}

 

启动:service-ribbon 工程,当咱们访问http://localhost:8764/hi?name=forezp,浏览器显示:

hi forezp,i am from port:8762

此时关闭 service-hi 工程,当咱们再访问http://localhost:8764/hi?name=forezp,浏览器会显示:

hi ,forezp,orry,error!

这就说明当 service-hi 工程不可用的时候,service-ribbon调用 service-hi的API接口时,会执行快速失败,直接返回一组字符串,而不是等待响应超时,这很好的控制了容器的线程阻塞。

4、Feign中使用断路器

Feign是自带断路器的,在D版本的Spring Cloud中,它没有默认打开。须要在配置文件中配置打开它,在配置文件加如下代码:

feign.hystrix.enabled=true

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka/

server:

  port: 8765

spring:

  application:

    name: service-feign

feign:

  hystrix:

    enabled:

      true   

 

基于service-feign工程进行改造,只须要在FeignClient的SchedualServiceHi接口的注解中加上fallback的指定类就好了:

value"service-hi"@FeignClient(=,fallback = SchedualServiceHiHystric.class)
publicinterfaceSchedualServiceHi {
value"/hi"    @RequestMapping(=,method = RequestMethod.GET)
value"name"    String sayHiFromClientOne(@RequestParam(=) String name);
}

 

SchedualServiceHiHystric须要实现SchedualServiceHi 接口,并注入到Ioc容器中,代码以下:

@Component
publicclass SchedualServiceHiHystric implements SchedualServiceHi {
@Override   
publicsayHiFromClientOne   String(String name) {
return"sorry "       +name;
    }
}

 

启动四servcie-feign工程,浏览器打开http://localhost:8765/hi?name=forezp,注意此时service-hi工程没有启动,网页显示:

sorry forezp

打开service-hi工程,再次访问,浏览器显示:

hi forezp,i am from port:8762

这证实断路器起到做用了。

5、Hystrix Dashboard (断路器:Hystrix 仪表盘)

基于service-ribbon 改造,Feign的改造和这同样。

首选在pom.xml引入spring-cloud-starter-hystrix-dashboard的起步依赖:

<dependency>
<groupId></groupId>           org.springframework.boot
<artifactId></artifactId>           spring-boot-starter-actuator
</dependency>       
 
<dependency>       
<groupId></groupId>           org.springframework.cloud
<artifactId></artifactId>           spring-cloud-starter-hystrix-dashboard
</dependency>       

在主程序启动类中加入@EnableHystrixDashboard注解,开启hystrixDashboard:

@SpringBootApplication
@EnableDiscoveryClient
@EnableHystrix
@EnableHystrixDashboard
publicclass ServiceRibbonApplication {
 
publicstaticvoidmain   (String[] args) {
        SpringApplication.run(ServiceRibbonApplication.class, args);
    }
 
@Bean   
@LoadBalanced   
    RestTemplate restTemplate() {
returnnew       RestTemplate();
    }
 
}

打开浏览器:访问http://localhost:8764/hystrix,界面以下:

 

点击monitor stream,进入下一个界面,访问:http://localhost:8764/hi?name=forezp

此时会出现监控界面:

 

5.路由网关(zuul)

在微服务架构中,须要几个基础的服务治理组件,包括服务注册与发现、服务消费、负载均衡、断路器、智能路由、配置管理等,由这几个基础组件相互协做,共同组建了一个简单的微服务系统。一个简单的微服务系统以下图:

 
注意:A服务和B服务是能够相互调用的,做图的时候忘记了。而且配置服务也是注册到服务注册中心的。

在Spring Cloud微服务系统中,一种常见的负载均衡方式是,客户端的请求首先通过负载均衡(zuul、Ngnix),再到达服务网关(zuul集群),而后再到具体的服。,服务统一注册到高可用的服务注册中心集群,服务的全部的配置文件由配置服务管理(下一篇文章讲述),配置服务的配置文件放在git仓库,方便开发人员随时改配置。

1、Zuul简介

Zuul的主要功能是路由转发和过滤器。路由功能是微服务的一部分,好比/api/user转发到user服务,/api/shop转发到shop服务。zuul默认和Ribbon结合实现了负载均衡的功能。

zuul有如下功能:

  • Authentication
  • Insights
  • Stress Testing
  • Canary Testing
  • Dynamic Routing
  • Service Migration
  • Load Shedding
  • Security
  • Static Response handling
  • Active/Active traffic management

2、准备工做

继续使用上一节的工程。在原有的工程上,建立一个新的工程。

3、建立service-zuul工程

其pom.xml文件以下:

<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.forezp</groupId>

  <artifactId>service-zuul</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>service-zuul</name>

  <description>Demo project for Spring Boot</description>

 

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-zuul</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

 

</project>

 

在其入口applicaton类加上注解@EnableZuulProxy,开启zuul的功能:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

 

@EnableZuulProxy

@EnableEurekaClient

@SpringBootApplication

public class ServiceZuulApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ServiceZuulApplication.class, args);

    }

}

 

加上配置文件application.yml加上如下的配置代码:

eureka:

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka/

server:

  port: 8769

spring:

  application:

    name: service-zuul

zuul:

  routes:

    api-a:

      path: /api-a/**

      serviceId: service-ribbon

    api-b:

      path: /api-b/**

      serviceId: service-feign

 

首先指定服务注册中心的地址为http://localhost:8761/eureka/,服务的端口为8769,服务名为service-zuul;以/api-a/ 开头的请求都转发给service-ribbon服务;以/api-b/开头的请求都转发给service-feign服务;

依次运行这五个工程;打开浏览器访问:http://localhost:8769/api-a/hi?name=forezp ;浏览器显示:

hi forezp,i am from port:8762

打开浏览器访问:http://localhost:8769/api-b/hi?name=forezp ;浏览器显示:

hi forezp,i am from port:8762

这说明zuul起到了路由的做用

4、服务过滤

zuul不只只是路由,而且还能过滤,作一些安全验证。继续改造工程;

package com.forezp;

import com.netflix.zuul.ZuulFilter;

import com.netflix.zuul.context.RequestContext;

import org.slf4j.Logger;

import org.slf4j.LoggerFactory;

import org.springframework.stereotype.Component;

 

import javax.servlet.http.HttpServletRequest;

 

@Component

public class MyFilter extends ZuulFilter{

 

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

    @Override

    public String filterType() {

        return "pre";

    }

 

    @Override

    public int filterOrder() {

        return 0;

    }

 

    @Override

    public boolean shouldFilter() {

        return true;

    }

 

    @Override

    public Object run() {

        RequestContext ctx = RequestContext.getCurrentContext();

        HttpServletRequest request = ctx.getRequest();

        log.info(String.format("%s >>> %s", request.getMethod(), request.getRequestURL().toString()));

        Object accessToken = request.getParameter("token");

        if(accessToken == null) {

            log.warn("token is empty");

            ctx.setSendZuulResponse(false);

            ctx.setResponseStatusCode(401);

            try {

                ctx.getResponse().getWriter().write("token is empty");

            }catch (Exception e){}

 

            return null;

        }

        log.info("ok");

        return null;

    }

}

  • filterType:返回一个字符串表明过滤器的类型,在zuul中定义了四种不一样生命周期的过滤器类型,具体以下: 

    • pre:路由以前
    • routing:路由之时
    • post: 路由以后
    • error:发送错误调用
    • filterOrder:过滤的顺序
    • shouldFilter:这里能够写逻辑判断,是否要过滤,本文true,永远过滤。
    • run:过滤器的具体逻辑。可用很复杂,包括查sql,nosql去判断该请求到底有没有权限访问。

这时访问:http://localhost:8769/api-a/hi?name=forezp ;网页显示:

token is empty

访问 http://localhost:8769/api-a/hi?name=forezp&token=22 ; 
网页显示:

hi forezp,i am from port:8762

6.分布式配置中心(Spring Cloud Config)

1、简介

在分布式系统中,因为服务数量巨多,为了方便服务配置文件统一管理,实时更新,因此须要分布式配置中心组件。在Spring Cloud中,有分布式配置中心组件spring cloud config ,它支持配置服务放在配置服务的内存中(即本地),也支持放在远程Git仓库中。在spring cloud config 组件中,分两个角色,一是config server,二是config client。

2、构建Config Server

建立一个spring-boot项目,取名为config-server,其pom.xml:

<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.forezp</groupId>

  <artifactId>config-server</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>config-server</name>

  <description>Demo project for Spring Boot</description>

 

   <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-config-server</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Camden.SR6</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

 

在程序的入口Application类加上@EnableConfigServer注解开启配置服务器的功能,代码以下:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.config.server.EnableConfigServer;

 

@SpringBootApplication

@EnableConfigServer

public class ConfigServerApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ConfigServerApplication.class, args);

    }

}

 

 

须要在程序的配置文件application.properties文件配置如下:

spring.application.name=config-server

server.port=8888

 

spring.cloud.config.server.git.uri=https://github.com/forezp/SpringcloudConfig/

spring.cloud.config.server.git.searchPaths=respo

spring.cloud.config.label=master

spring.cloud.config.server.git.username=

spring.cloud.config.server.git.password=

 

spring.cloud.config.server.git.uri:配置git仓库地址

spring.cloud.config.server.git.searchPaths:配置仓库路径

spring.cloud.config.label:配置仓库的分支

spring.cloud.config.server.git.username:访问git仓库的用户名

spring.cloud.config.server.git.password:访问git仓库的用户密码

若是Git仓库为公开仓库,能够不填写用户名和密码,若是是私有仓库须要填写,本例子是公开仓库,放心使用。

远程仓库https://github.com/forezp/SpringcloudConfig/ 中有个文件config-client-dev.properties文件中有一个属性:

foo = foo version 3

启动程序:访问http://localhost:8888/foo/dev

name"foo"profiles["dev"]label"master"{"":,"":,"":,
version"792ffc77c03f4b138d28e89b576900ac5e01a44b"statenullpropertySources[]"":,"":,"":}

证实配置服务中心能够从远程程序获取配置信息。

http请求地址和资源文件映射以下:

  • /{application}/{profile}[/{label}]
  • /{application}-{profile}.yml
  • /{label}/{application}-{profile}.yml
  • /{application}-{profile}.properties
  • /{label}/{application}-{profile}.properties

3、构建一个config client

从新建立一个springboot项目,取名为config-client,其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.forezp</groupId>

  <artifactId>config-client</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>config-client</name>

  <description>Demo project for Spring Boot</description>

 

  <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.cloud</groupId>

            <artifactId>spring-cloud-starter-config</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

 

其配置文件bootstrap.properties

spring.application.name=config-client

spring.cloud.config.label=master

spring.cloud.config.profile=dev

spring.cloud.config.uri= http://localhost:8888/

server.port=8881

 

 spring.cloud.config.label 指明远程仓库的分支

  • spring.cloud.config.profile
    • dev开发环境配置文件
    • test测试环境
    • pro正式环境
    • spring.cloud.config.uri= http://localhost:8888/ 指明配置服务中心的网址。

程序的入口类,写一个API接口“/hi”,返回从配置中心读取的foo变量的值,代码以下:

package com.forezp;

 

import org.springframework.beans.factory.annotation.Value;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

 

@SpringBootApplication

@RestController

public class ConfigClientApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ConfigClientApplication.class, args);

    }

 

    @Value("${foo}")

    String foo;

    @RequestMapping(value = "/hi")

    public String hi(){

        return foo;

    }

}

 

打开网址访问:http://localhost:8881/hi,网页显示:

foo version 3

这就说明,config-client从config-server获取了foo的属性,而config-server是从git仓库读取的,如图:

 

7. 高可用的分布式配置中心(Spring Cloud Config)

上一篇文章讲述了一个服务如何从配置中心读取文件,配置中心如何从远程git读取配置文件,当服务实例不少时,都从配置中心读取文件,这时能够考虑将配置中心作成一个微服务,将其集群化,从而达到高可用,架构图以下:

 

1、准备工做

继续使用上一篇文章的工程,建立一个eureka-server工程,用做服务注册中心。

在其pom.xml文件引入Eureka的起步依赖spring-cloud-starter-eureka-server,代码以下:

<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.forezp</groupId>

      <artifactId>eureka-server</artifactId>

      <version>0.0.1-SNAPSHOT</version>

      <packaging>jar</packaging>

 

      <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath /> <!-- lookup parent from repository -->

      </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.cloud</groupId>

                 <artifactId>spring-cloud-starter-eureka-server</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-web</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Dalston.RC1</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

</project>

在配置文件application.yml上,指定服务端口为8889,加上做为服务注册中心的基本配置,代码以下:

server:

  port: 8889

 

eureka:

  instance:

    hostname: localhost

  client:

    registerWithEureka: false

    fetchRegistry: false

    serviceUrl:

      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

入口类:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

 

 

@EnableEurekaServer

@SpringBootApplication

public class EurekaServerApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(EurekaServerApplication.class, args);

    }

}

2、改造config-server

在其pom.xml文件加上EurekaClient的起步依赖spring-cloud-starter-eureka,代码以下:

<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.forezp</groupId>

  <artifactId>config-server</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>config-server</name>

  <description>Demo project for Spring Boot</description>

 

  <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath/> <!-- lookup parent from repository -->

      </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.cloud</groupId>

                 <artifactId>spring-cloud-config-server</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-eureka</artifactId>

           </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Camden.SR6</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

</project>

配置文件application.yml,指定服务注册地址为http://localhost:8889/eureka/,其余配置同上一篇文章,完整的配置以下:

spring.application.name=config-server

server.port=8888

 

spring.cloud.config.server.git.uri=https://github.com/forezp/SpringcloudConfig/

spring.cloud.config.server.git.searchPaths=respo

spring.cloud.config.label=master

spring.cloud.config.server.git.username=

spring.cloud.config.server.git.password=

eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/

入口类:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.config.server.EnableConfigServer;

import org.springframework.cloud.netflix.eureka.EnableEurekaClient;

 

@SpringBootApplication

@EnableConfigServer

@EnableEurekaClient

public class ConfigServerApplication {

 

    public static void main(String[] args) {

        SpringApplication.run(ConfigServerApplication.class, args);

    }

}

3、改造config-client

将其注册微到服务注册中心,做为Eureka客户端,须要pom文件加上起步依赖spring-cloud-starter-eureka,代码以下:

<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.forezp</groupId>

  <artifactId>config-client</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>config-client</name>

  <description>Demo project for Spring Boot</description>

 

  <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath/> <!-- lookup parent from repository -->

      </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.cloud</groupId>

                 <artifactId>spring-cloud-starter-config</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-web</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

          

           <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-config</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Dalston.RC1</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

</project>

配置文件bootstrap.properties,注意是bootstrap。加上服务注册地址为http://localhost:8889/eureka/

spring.application.name=config-client

spring.cloud.config.label=master

spring.cloud.config.profile=dev

#spring.cloud.config.uri= http://localhost:8888/

 

eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/

spring.cloud.config.discovery.enabled=true

spring.cloud.config.discovery.serviceId=config-server

server.port=8881

  • spring.cloud.config.discovery.enabled 是从配置中心读取文件。
  • spring.cloud.config.discovery.serviceId 配置中心的servieId,即服务名。

这时发现,在读取配置文件再也不写ip地址,而是服务名,这时若是配置服务部署多份,经过负载均衡,从而高可用。

依次启动eureka-servr,config-server,config-client 
访问网址:http://localhost:8889/

 

访问http://localhost:8881/hi,浏览器显示:

foo version 3

 

 

8.消息总线(Spring Cloud Bus)

Spring Cloud Bus 将分布式的节点用轻量的消息代理链接起来。它能够用于广播配置文件的更改或者服务之间的通信,也能够用于监控。本文要讲述的是用Spring Cloud Bus实现通知微服务架构的配置文件的更改。

1、准备工做

本文仍是基于上一篇文章来实现。按照官方文档,咱们只须要在配置文件中配置 spring-cloud-starter-bus-amqp ;这就是说咱们须要装rabbitMq

2、改造config-client

在pom文件加上起步依赖spring-cloud-starter-bus-amqp,完整的配置文件以下:

<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.forezp</groupId>

  <artifactId>config-client</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>config-client</name>

  <description>Demo project for Spring Boot</description>

 

 <parent>

        <groupId>org.springframework.boot</groupId>

        <artifactId>spring-boot-starter-parent</artifactId>

        <version>1.5.2.RELEASE</version>

        <relativePath/> <!-- lookup parent from repository -->

    </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.retry</groupId>

            <artifactId>spring-retry</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-config</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-web</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-aop</artifactId>

        </dependency>

 

 

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-eureka</artifactId>

        </dependency>

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-test</artifactId>

            <scope>test</scope>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.cloud</groupId>

            <artifactId>spring-cloud-starter-bus-amqp</artifactId>

        </dependency>

 

        <dependency>

            <groupId>org.springframework.boot</groupId>

            <artifactId>spring-boot-starter-actuator</artifactId>

        </dependency>

    </dependencies>

 

    <dependencyManagement>

        <dependencies>

            <dependency>

                <groupId>org.springframework.cloud</groupId>

                <artifactId>spring-cloud-dependencies</artifactId>

                <version>Dalston.RC1</version>

                <type>pom</type>

                <scope>import</scope>

            </dependency>

        </dependencies>

    </dependencyManagement>

 

    <build>

        <plugins>

            <plugin>

                <groupId>org.springframework.boot</groupId>

                <artifactId>spring-boot-maven-plugin</artifactId>

            </plugin>

        </plugins>

    </build>

 

    <repositories>

        <repository>

            <id>spring-milestones</id>

            <name>Spring Milestones</name>

            <url>https://repo.spring.io/milestone</url>

            <snapshots>

                <enabled>false</enabled>

            </snapshots>

        </repository>

    </repositories>

</project>

 

在配置文件application.properties中加上RabbitMq的配置,包括RabbitMq的地址、端口,用户名、密码,代码以下:

spring.application.name=config-client

spring.cloud.config.label=master

spring.cloud.config.profile=dev

#spring.cloud.config.uri= http://localhost:8888/

 

eureka.client.serviceUrl.defaultZone=http://localhost:8889/eureka/

spring.cloud.config.discovery.enabled=true

spring.cloud.config.discovery.serviceId=config-server

server.port=8882

 

spring.rabbitmq.host=localhost

spring.rabbitmq.port=15672

spring.rabbitmq.username=guest

spring.rabbitmq.password=guest

 

若是rabbitmq有用户名密码,输入便可。

依次启动eureka-server、confg-cserver,启动两个config-client,端口为:888一、8882。

访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:

foo version 3

这时咱们去代码仓库将foo的值改成“foo version 4”,即改变配置文件foo的值。若是是传统的作法,须要重启服务,才能达到配置文件的更新。此时,咱们只须要发送post请求:http://localhost:8881/bus/refresh,你会发现config-client会从新读取配置文件

 

从新读取配置文件:

 

这时咱们再访问http://localhost:8881/hi 或者http://localhost:8882/hi 浏览器显示:

foo version 4

另外,/bus/refresh接口能够指定服务,即便用”destination”参数,好比 “/bus/refresh?destination=customers:**” 即刷新服务名为customers的全部服务,无论ip。

3、分析

此时的架构图: 

当git文件更改的时候,经过pc端用post 向端口为8882的config-client发送请求/bus/refresh/;此时8882端口会发送一个消息,由消息总线向其余服务传递,从而使整个微服务集群都达到更新配置文件。

9. 服务链路追踪(Spring Cloud Sleuth)

这篇文章主要讲述服务追踪组件zipkin,Spring Cloud Sleuth集成了zipkin组件。

1、简介

Add sleuth to the classpath of a Spring Boot application (see below for Maven and Gradle examples), and you will see the correlation data being collected in logs, as long as you are logging requests.

—— 摘自官网

Spring Cloud Sleuth 主要功能就是在分布式系统中提供追踪解决方案,而且兼容支持了 zipkin,你只须要在pom文件中引入相应的依赖便可。

2、服务追踪分析

微服务架构上经过业务来划分服务的,经过REST调用,对外暴露的一个接口,可能须要不少个服务协同才能完成这个接口功能,若是链路上任何一个服务出现问题或者网络超时,都会造成致使接口调用失败。随着业务的不断扩张,服务之间互相调用会愈来愈复杂。

 

随着服务的愈来愈多,对调用链的分析会愈来愈复杂。它们之间的调用关系也许以下:

 

3、术语

  • Span:基本工做单元,例如,在一个新建的span中发送一个RPC等同于发送一个回应请求给RPC,span经过一个64位ID惟一标识,trace以另外一个64位ID表示,span还有其余数据信息,好比摘要、时间戳事件、关键值注释(tags)、span的ID、以及进度ID(一般是IP地址) 
    span在不断的启动和中止,同时记录了时间信息,当你建立了一个span,你必须在将来的某个时刻中止它。
  • Trace:一系列spans组成的一个树状结构,例如,若是你正在跑一个分布式大数据工程,你可能须要建立一个trace。
  • Annotation:用来及时记录一个事件的存在,一些核心annotations用来定义一个请求的开始和结束 

    • cs - Client Sent -客户端发起一个请求,这个annotion描述了这个span的开始
    • sr - Server Received -服务端得到请求并准备开始处理它,若是将其sr减去cs时间戳即可获得网络延迟
    • ss - Server Sent -注解代表请求处理的完成(当请求返回客户端),若是ss减去sr时间戳即可获得服务端须要的处理请求时间
    • cr - Client Received -代表span的结束,客户端成功接收到服务端的回复,若是cr减去cs时间戳即可获得客户端从服务端获取回复的全部所需时间 
      将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

将Span和Trace在一个系统中使用Zipkin注解的过程图形化:

 

4、构建工程

基本知识讲解完毕,下面咱们来实战,本文的案例主要有三个工程组成:一个server-zipkin,它的主要做用使用ZipkinServer 的功能,收集调用数据,并展现;一个service-hi,对外暴露hi接口;一个service-miya,对外暴露miya接口;这两个service能够相互调用;而且只有调用了,server-zipkin才会收集数据的,这就是为何叫服务追踪了。

4.1 构建server-zipkin

建一个spring-boot工程取名为server-zipkin,在其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.forezp</groupId>

  <artifactId>server-zipkin</artifactId>

  <version>0.0.1-SNAPSHOT</version>

  <name>server-zipkin</name>

  <description>Demo project for Spring Boot</description>

 

  <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath/> <!-- lookup parent from repository -->

      </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</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-web</artifactId>

           </dependency>

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

 

           <dependency>

                 <groupId>io.zipkin.java</groupId>

                 <artifactId>zipkin-server</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>io.zipkin.java</groupId>

                 <artifactId>zipkin-autoconfigure-ui</artifactId>

           </dependency>

 

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Camden.SR6</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

</project>

 

在其程序入口类, 加上注解@EnableZipkinServer,开启ZipkinServer的功能:

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import zipkin.server.EnableZipkinServer;

 

@SpringBootApplication

@EnableZipkinServer

public class ServerZipkinApplication {

 

      public static void main(String[] args) {

           SpringApplication.run(ServerZipkinApplication.class, args);

      }}

 

在配置文件application.properties指定服务端口为:

server.port9411=

4.2 建立service-hi

在其pom引入起步依赖spring-cloud-starter-zipkin,代码以下:

<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.forezp</groupId>

  <artifactId>service-hi</artifactId>

  <version>0.0.1-SNAPSHOT</version>

 

  <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath/> <!-- lookup parent from repository -->

      </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-web</artifactId>

           </dependency>

           <!--compile('org.springframework.cloud:spring-cloud-starter-zipkin')-->

 

           <dependency>

                 <groupId>org.springframework.cloud</groupId>

                 <artifactId>spring-cloud-starter-zipkin</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Dalston.RC1</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

 

</project>

 

在其配置文件application.properties指定zipkin server的地址,头经过配置“spring.zipkin.base-url”指定:

 
.port8988server=
.zipkin.base9411spring-url=http://localhost:
.application.namespring=service-hi

经过引入spring-cloud-starter-zipkin依赖和设置spring.zipkin.base-url就能够了。

入口类对外暴露接口:

package com.forezp;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

import org.springframework.cloud.sleuth.sampler.AlwaysSampler;

import java.util.logging.Level;

import java.util.logging.Logger;

 

@SpringBootApplication

@RestController

public class ServiceHiApplication {

 

      public static void main(String[] args) {

           SpringApplication.run(ServiceHiApplication.class, args);

      }

 

      private static final Logger LOG = Logger.getLogger(ServiceHiApplication.class.getName());

 

 

      @Autowired

      private RestTemplate restTemplate;

 

      @Bean

      public RestTemplate getRestTemplate(){

           return new RestTemplate();

      }

 

      @RequestMapping("/hi")

      public String callHome(){

           LOG.log(Level.INFO, "calling trace service-hi  ");

           return restTemplate.getForObject("http://localhost:8989/miya", String.class);

      }

      @RequestMapping("/info")

      public String info(){

           LOG.log(Level.INFO, "calling trace service-hi ");

 

           return "i'm service-hi";

 

      }

 

      @Bean

      public AlwaysSampler defaultSampler(){

           return new AlwaysSampler();

      }

}

 

4.3 建立service-miya

建立过程同service-hi,引入相同的依赖,配置下spring.zipkin.base-url。

server.port=8989

spring.zipkin.base-url=http://localhost:9411

spring.application.name=service-miya

 

对外暴露接口:

package com.forezp;

 

import org.springframework.beans.factory.annotation.Autowired;

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.context.annotation.Bean;

import org.springframework.web.bind.annotation.RequestMapping;

import org.springframework.web.bind.annotation.RestController;

import org.springframework.web.client.RestTemplate;

 

import java.util.logging.Level;

import java.util.logging.Logger;

 

@SpringBootApplication

@RestController

public class ServiceMiyaApplication {

 

      public static void main(String[] args) {

           SpringApplication.run(ServiceMiyaApplication.class, args);

      }

 

      private static final Logger LOG = Logger.getLogger(ServiceMiyaApplication.class.getName());

 

 

      @RequestMapping("/hi")

      public String home(){

           LOG.log(Level.INFO, "hi is being called");

           return "hi i'm miya!";

      }

 

      @RequestMapping("/miya")

      public String info(){

           LOG.log(Level.INFO, "info is being called");

           return restTemplate.getForObject("http://localhost:8988/info",String.class);

      }

 

      @Autowired

      private RestTemplate restTemplate;

 

      @Bean

      public RestTemplate getRestTemplate(){

           return new RestTemplate();

      }

}

 

 

4.4 启动工程,演示追踪

依次启动上面的三个工程,打开浏览器访问:http://localhost:9411/,会出现如下界面:

 

访问:http://localhost:8988/hi,浏览器出现:

i’m service-hi

再打开http://localhost:9411/的界面,点击Dependencies,能够发现服务的依赖关系:

 

点击find traces,能够看到具体服务相互调用的数据:

 

10.高可用的服务注册中心

服务注册中心Eureka Server,是一个实例,当成千上万个服务向它注册的时候,它的负载是很是高的,这在生产环境上是不太合适的,这篇文章主要介绍怎么将Eureka Server集群化。

高可用的注册中心实现思路

Eureka经过“伙伴”机制实现高可用。每一台Eureka都须要在配置中指定另外一个Eureka的地址做为伙伴,Eureka启动时会向本身的伙伴节点获取当前已经存在的注册列表, 这样在向Eureka集群中新加机器时就不须要担忧注册列表不完整的问题。

除此以外,Eureka还支持Region和Zone的概念。其中一个Region能够包含多个Zone。Eureka在启动时须要指定一个Zone名,即当前Eureka属于哪一个zone, 若是不指定则属于defaultZone。Eureka Client也须要指定Zone, Client(当与Ribbon配置使用时)在向Server获取注册列表时会优先向本身Zone的Eureka发请求,若是本身Zone中的Eureka全挂了才会尝试向其它Zone。Region和Zone能够对应于现实中的大区和机房,如在华北地区有10个机房,在华南地区有20个机房,那么分别为Eureka指定合理的Region和Zone能有效避免跨机房调用,同时一个地区的Eureka坏掉不会致使整个该地区的服务都不可用。

本文咱们经过运行eureka-server多个实例,并进行互相注册的方式来实现高可用的部署,咱们只须要将Eureke Server配置其余可用的serviceUrl就能实现高可用部署。

咱们能够建立三个注册中心节点,每一个节点进行两两注册,实现彻底对等的效果,能够达到集群的最高可用性,任何一个节点挂掉都不会影响服务的注册与发现。

 

1、服务器准备

在winsow环境下测试 ,打开C:\Windows\System32\drivers\etc的hosts文件,添加下列内容
127.0.0.1   eureka-server-peer1 
127.0.0.1   eureka-server-peer2 
127.0.0.1   eureka-server-peer3 

2、建立三个项目

项目名称分别为spring-cloud-server、spring-cloud-server_一、spring-cloud-server_2;

Pom.xml均为

<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.springcloud</groupId>

  <artifactId>spring-cloud-server_2</artifactId>

  <version>0.0.1-SNAPSHOT</version>

 

  <parent>

           <groupId>org.springframework.boot</groupId>

           <artifactId>spring-boot-starter-parent</artifactId>

           <version>1.5.2.RELEASE</version>

           <relativePath/> <!-- lookup parent from repository -->

      </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.cloud</groupId>

                 <artifactId>spring-cloud-starter-eureka-server</artifactId>

           </dependency>

 

           <dependency>

                 <groupId>org.springframework.boot</groupId>

                 <artifactId>spring-boot-starter-test</artifactId>

                 <scope>test</scope>

           </dependency>

      </dependencies>

 

      <dependencyManagement>

           <dependencies>

                 <dependency>

                      <groupId>org.springframework.cloud</groupId>

                      <artifactId>spring-cloud-dependencies</artifactId>

                      <version>Dalston.RC1</version>

                      <type>pom</type>

                      <scope>import</scope>

                 </dependency>

           </dependencies>

      </dependencyManagement>

 

      <build>

           <plugins>

                 <plugin>

                      <groupId>org.springframework.boot</groupId>

                      <artifactId>spring-boot-maven-plugin</artifactId>

                 </plugin>

           </plugins>

      </build>

 

      <repositories>

           <repository>

                 <id>spring-milestones</id>

                 <name>Spring Milestones</name>

                 <url>https://repo.spring.io/milestone</url>

                 <snapshots>

                      <enabled>false</enabled>

                 </snapshots>

           </repository>

      </repositories>

 

</project>

 

3、修改application.properties

spring-cloud-server的

server.port=8761

spring.application.name=microservice-eureka-server

spring.profiles=peer1

eureka.instance.hostname=eureka-server-peer1

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.client.serviceUrl.defaultZone=http://eureka-server-peer2:8762/eureka/,http://eureka-server-peer3:8763/eureka/

 

spring-cloud-server_1的

server.port=8762

spring.application.name=microservice-eureka-server

spring.profiles=peer2

eureka.instance.hostname=eureka-server-peer2

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.client.serviceUrl.defaultZone=http://eureka-server-peer1:8761/eureka/,http://eureka-server-peer3:8763/eureka/

 

spring-cloud-server_2的

server.port=8763

spring.application.name=microservice-eureka-server

spring.profiles=peer3

eureka.instance.hostname=eureka-server-peer3

eureka.client.register-with-eureka=false

eureka.client.fetch-registry=false

eureka.client.serviceUrl.defaultZone=http://eureka-server-peer1:8761/eureka/,http://eureka-server-peer2:8762/eureka/

 

4、启动类

更改对应的类名便可

package com.forezp;

 

import org.springframework.boot.SpringApplication;

import org.springframework.boot.autoconfigure.SpringBootApplication;

import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;

 

@EnableEurekaServer

@SpringBootApplication

public class EurekaServerApplication {

 

      public static void main(String[] args) {

           SpringApplication.run(EurekaServerApplication.class, args);

      }

}

 

 

5、分别启动三个项目

访问http://localhost:8761/  能够看到DS Replicas中出现peer二、peer3

 

 

同理访问http://localhost:8762/  能够看到peer一、peer3节点;访问http://localhost:8763/  能够看到peer一、peer2节点;

 

6、建立一个服务提供者 (eureka client)

参考1中步骤,其中配置信息以下:

eureka:

  client:

    serviceUrl:

      defaultZone: http://eureka-server-peer1:8761/eureka/

server:

  port: 8888

spring:

  application:

    name: service-hi

启动后,发现分别访问http://localhost:8761/ 、http://localhost:8762/ 、http://localhost:8763/ ,都可看到service-hi注册在服务中

 

 

当关闭spring-cloud-server服务,访问http://localhost:8762/ 、http://localhost:8763/ ,一样能够看到service-hi注册在服务中。这样就实现了集群的高可用。

相关文章
相关标签/搜索