4. person服务模块
依赖
<?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>
<parent>
<artifactId>springCloud</artifactId>
<groupId>com.abel</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<artifactId>person</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</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-data-jpa</artifactId>
</dependency>
<dependency>
<groupId>org.hsqldb</groupId>
<artifactId>hsqldb</artifactId>
</dependency>
<dependency>
<groupId>postgresql</groupId>
<artifactId>postgresql</artifactId>
<version>9.1-901-1.jdbc4</version>
</dependency>
</dependencies>
</project>
关键代码
此处为关键代码,完整代码请看文章底部的git 地址
package com.abel.controller;
import com.abel.bean.Person;
import com.abel.dao.PersonRepository;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.PageRequest;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import java.util.List;
/**
* Created by yangyibo on 2018/6/27.
*/
@RestController
public class PersonController {
@Autowired
PersonRepository personRepository;
@RequestMapping(value = "/save", method = RequestMethod.POST)
public List<Person> savePerson(@RequestBody String personName) {
Person p = new Person(personName);
personRepository.save(p);
List<Person> people = personRepository.findAll(new PageRequest(0, 10)).getContent();
return people;
}
}
配置
在resource 下新建application.yml 和bootstrap.yml文件
application.yml
server:
port: 8082
spring:
jpa:
hibernate:
ddl-auto: update
bootstrap.yml
spring:
application:
name: person
cloud:
config:
enabled: true
discovery:
enabled: true
service-id: CONFIG #1
eureka:
instance:
non-secure-port: ${server.port:8082}
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
注意,在配置服务config 的resource 下新建config文件夹,并配置person 服务
在config 文件夹下新建person.yml 配置文件内容如下:
spring:
jpa:
database: HSQL
5. some服务模块
依赖
<?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">
<parent>
<artifactId>springCloud</artifactId>
<groupId>com.abel</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>some</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
</dependencies>
</project>
关键代码
package com.abel;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by yangyibo on 2018/6/28.
*/
@SpringBootApplication
@EnableDiscoveryClient
@RestController
public class SomeApplication {
@Value("${my.message}") //Value 值来自于config server
private String message;
@RequestMapping(value = "/getsome")
public String getsome(){
return message;
}
public static void main(String[] args) {
SpringApplication.run(SomeApplication.class, args);
}
}
配置
在resource 下新建application.yml 和bootstrap.yml文件
application.yml
server:
port: 8083
bootstrap.yml
spring:
application:
name: some
cloud:
config:
enabled: true
discovery:
enabled: true
service-id: CONFIG
eureka:
instance:
non-secure-port: ${server.port:8083}
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
注意,在配置服务config 的resource 下新建config文件夹,并配置some服务
在config 文件夹下新建some.yml 配置文件内容如下:
my:
message: Message from Development
6. 界面模块-UI
依赖
<parent>
<artifactId>springCloud</artifactId>
<groupId>com.abel</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>ui</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</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-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-config-client</artifactId>
</dependency>
<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.cloud</groupId>
<artifactId>spring-cloud-starter-ribbon</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>bootstrap</artifactId>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angularjs</artifactId>
<version>1.3.15</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>angular-ui-router</artifactId>
<version>0.2.13</version>
</dependency>
<dependency>
<groupId>org.webjars</groupId>
<artifactId>jquery</artifactId>
</dependency>
</dependencies>
关键代码
package com.abel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* Created by yangyibo on 2018/6/29.
*/
@SpringBootApplication
@EnableEurekaClient
@EnableFeignClients //开启fegin 客户端支持
@EnableCircuitBreaker //开启CircuitBreaker的支持
@EnableZuulProxy //开启网关代理支持
public class UiApplication {
public static void main(String[] args) {
SpringApplication.run(UiApplication.class, args);
}
}
调用 person的断路器 PersonHystrixService
package com.abel.service;
import com.abel.bean.Person;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.List;
/**
* Created by yangyibo on 2018/6/29.
* 调用person service的断路器
*/
@Service
public class PersonHystrixService {
@Autowired
PersonService personService;
@HystrixCommand(fallbackMethod = "fallbackSave") //使用HystrixCommand的fallbackMethod参数指定,调用失败的时候调用后备方法 fallbackMethod
public List<Person> save(String name) {
return personService.save(name);
}
public List<Person> fallbackSave(String name){
List<Person> list = new ArrayList<Person>();
Person p = new Person(name+"没有保存成功,Person Service 故障");
list.add(p);
return list;
}
}
使用ribbo 调用some 服务并使用断路器
package com.abel.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;
/**
* Created by yangyibo on 2018/6/29.
* 使用ribbon 调用some service 并使用断路器
*/
@Service
public class SomeHystrixService {
@Autowired
RestTemplate restTemplate; // springboot 下使用ribbon ,只需注入一个 RestTemplate,springboot 已经为我们做好了配置
@HystrixCommand(fallbackMethod = "fallbackSome") //HystrixCommand 的参数指定,当调用失败时,使用备用方法fallbackMethod
public String getSome() {
return restTemplate.getForObject("http://some/getsome", String.class);
}
public String fallbackSome(){
return "some service模块故障";
}
}
配置
在resource 下新建application.yml 和bootstrap.yml文件
application.yml
server:
port: 80
bootstrap.yml
spring:
application:
name: ui
eureka:
instance:
non-secure-port: ${server.port:80}
client:
service-url:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
7. 断路器监控
依赖
<parent>
<artifactId>springCloud</artifactId>
<groupId>com.abel</groupId>
<version>1.0-SNAPSHOT</version>
<relativePath>../pom.xml</relativePath>
</parent>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>com.spotify</groupId>
<artifactId>docker-maven-plugin</artifactId>
<configuration>
<imageName>${project.name}:${project.version}</imageName>
<dockerDirectory>${project.basedir}/src/main/docker</dockerDirectory>
<skipDockerBuild>false</skipDockerBuild>
<resources>
<resource>
<directory>${project.build.directory}</directory>
<include>${project.build.finalName}.jar</include>
</resource>
</resources>
</configuration>
</plugin>
</plugins>
</build>
关键代码
package com.abel;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
/**
* Created by yangyibo on 2018/6/29.
*/
@SpringBootApplication
@EnableEurekaClient
@EnableHystrixDashboard
@EnableTurbine
public class MonitorApplication {
public static void main(String[] args) {
SpringApplication.run(MonitorApplication.class, args);
}
}
配置
在resource 下新建application.yml 和 bootstrap.yml 文件
application.yml
server:
port: 8989
bootstrap.yml
spring:
application:
name: monitor
eureka:
instance:
nonSecurePort: ${server.port:8989}
client:
serviceUrl:
defaultZone: http://${eureka.host:localhost}:${eureka.port:8761}/eureka/
8.启动
我们一次启动 DiscoveryApplication、ConfigApplication,后面的所有微服务启动部分顺序,最后启动MonitorApplication。此时访问http://localhost:8761/,查看Eureka Server,如图:
(1) 访问UI服务
UI 服务是我们页面,也是我们的网关代理。在实际生产环境中,服务器防火墙只需将此端口暴露给外网即可,访问 http://localhost/#/person 如图
调用Person Service 服务 如图
调用some service 如图
(2)断路器
此时停止Person Service和SomeService,观察断路器的效果,界面会显示 服务故障
(3)断路器监控
访问http://localhost:8989/hystrix.stream 如图
输入 http://localhost/hystrix.stream 如图
监控界面如图
本文参考:《JavaEE开发的颠覆者:Spring Boot实战 》
本文完整源代码:https://github.com/527515025/springBoot/tree/master/springboot-springCloud