踩在巨人的肩膀上搭建了spring-cloud的demo,并且实现了服务的注册和发现、熔断、网关、负载、统一配置、消息总线等最简单的列子。
项目源码:http://git.oschina.net/siliangysd/spring-cloud
项目结构图:
eureka-server:服务注册中心
config-server:统一配置
zuul:网关服务
clienta、clientb :客户端
service-a、service-b:服务端
1、首先创建一个父项目:pom.xml
<?xml version="1.0" encoding="UTF-8"?>
<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>cn.cloud</groupId>
<artifactId>demo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<modules>
<module>eureka-server</module>
<module>service-a</module>
<module>clienta</module>
<module>service-b</module>
<module>clientb</module>
<module>zuul</module>
<module>config-server</module>
</modules>
<packaging>pom</packaging>
<name>demo</name>
<description>Demo project for Spring Boot</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.4.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>
<spring-cloud.version>Dalston.SR1</spring-cloud.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>${spring-cloud.version}</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>
2、新建eureka-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">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.cloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>eureka</artifactId>
<packaging>jar</packaging>
<name>eureka</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
</dependency>
</dependencies>
</project>
application.yml
server:
port: 8010 #服务端口
eureka:
instance:
hostname: localhost
server:
enable-self-preservation: false
eviction-interval-timer-in-ms: 4000
client:
register-with-eureka: false #是否将eureka自身作为应用注册到eureka注册中心
fetch-registry: false #为true时,可以启动,但报异常:Cannot execute request on any known server
serviceUrl:
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
启动服务,访问localhost:8010
2、创建项目service-a
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">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.cloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>service-a</artifactId>
<packaging>jar</packaging>
<name>service-a</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>junit</groupId>
<artifactId>junit</artifactId>
<version>3.8.1</version>
<scope>test</scope>
</dependency>
</dependencies>
</project>
application.yml
spring:
application:
name: service-a
server:
port: 8810
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8010/eureka/ #eureka服务注册地址
启动服务,再次访问localhost:8010
如图看到多出一个service-a的服务,注册、发现成功。
3、创建service-b项目 和service-a项目一致,将端口号修改一下。
a)如果需要测试负载请将application.yml 里的name 改为一致,启动
可以看到service-a的服务里有2台
b)如果测试网关请将name 改为不一致。
4、创建clienta项目
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">
<parent>
<artifactId>demo</artifactId>
<groupId>cn.cloud</groupId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>client-a</artifactId>
<packaging>jar</packaging>
<name>client-a</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-config</artifactId>
</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>
</project>
bootstrap.yml
server:
port: 8910
eureka:
client:
healthcheck:
enabled: true
serviceUrl:
defaultZone: http://localhost:8010/eureka/
instance:
lease-expiration-duration-in-seconds: 30
lease-renewal-interval-in-seconds: 10
spring:
application:
name: client-a
cloud:
config:
discovery:
enabled: true
service-id: config-server
profile: dev
label: master
rabbitmq:
host: localhost
port: 5672
username: guest
password: guest
management:
security:
enabled: false
在ClientApplication里开启@EnableHystrix 熔断注解
controller里的方法上可以添加 @HystrixCommand(fallbackMethod = “error”)
error 为方法名:
package cn.cloud.controller;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.cloud.context.config.annotation.RefreshScope;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
/**
* Created by Administrator on 2017/6/29.
*/
@RestController
@RefreshScope
public class TestController {
@Autowired
RestTemplate restTemplate;
@Value("${ip}")
private String ip;
@Value("${port}")
private String port;
@RequestMapping("/hi")
@HystrixCommand(fallbackMethod = "error")
public String hi(@RequestParam String id){
return restTemplate.getForObject("http://service-a/hi?id="+id, String.class);
}
public String error(String id){
return "hi, " + id + ", error!";
}
@RequestMapping("/getProperties")
public String getProperties(){
return ip + " : " + port;
}
}
5、clientb 项目
使用Feign来实现,具体见代码
6、创建config-server
application.yml
server:
port: 8030
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8010/eureka/ #eureka服务注册地址
# git管理配置
spring:
cloud:
config:
server:
git:
uri: http://git.oschina.net/siliangysd/spring-cloud #git仓库地址
searchPaths: demo* #搜索路径
username:
password:
application:
name: config-server
management:
security:
enabled: false
注意security这里的配置,这边我关闭了 不然消息总线的刷新会被拦截。
7、最后就是zuul了
主要是application.yml配置
spring:
application:
name: zuul
server:
port: 8020
eureka:
client:
service-url:
defaultZone: http://localhost:8010/eureka/
zuul:
routes:
api-a:
path: /service-a/**
serviceId: service-a
api-b:
path: /service-b/**
serviceId: service-b
sensitive-headers: #设置忽略的头信息,设置为空能解决会话保持问题
add-host-header: true #设为true才能保持Host头信息处理正确
ps:测试统一配置的刷新 ,需要rabbitmq的支持。
详见:http://www.cnblogs.com/andyfengzp/p/6830679.html 这篇文章 。