spring cloud的架构至少需要几个应用才能展示,所以我下面的源码将建立三个应用。应用需要jdk8运行环境。
1.eureka 注册中心,端口:1112
2.eFeignServer 展示一个注册到中心的Feign应用,并且调用Feign模式的远程接口,端口:8083
3.eFeignClient 另外一个注册的应用,就是个普通rest的应用,实际上跟Feign无关。端口:8084
代码下载链接:https://download.csdn.net/download/rishengcsdn/11166651
代码如下:
eureka 注册中心
==================================================
启动类:
package com.ecctest.eureka.springboot;
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);
}
}
======================================================
application.yml内容:
server:
port: 1112
eureka:
instance:
preferIpAddress: true
# 心跳时间,即服务续约间隔时间(缺省为30s)
lease-renewal-interval-in-seconds: 5
# 发呆时间,即服务续约到期时间(缺省为90s)
lease-expiration-duration-in-seconds: 10
server:
# 指定 Eviction Task 定时任务的调度频率,用于剔除过期的实例,此处未使用默认频率,频率为:5/秒,默认为:60/秒
# 有效防止的问题是:应用实例异常挂掉,没能在挂掉之前告知Eureka server要下线掉该服务实例信息。这个就需要依赖Eureka server的EvictionTask去剔除。
# 清理无效节点的时间间隔
eviction-interval-timer-in-ms: 5000
# 此处不开启缓存
use-read-only-response-cache: false
# 设置read Write CacheMap的expire After Write参数,指定写入多长时间后过期
# 有效防止的问题是:应用实例下线时有告知Eureka server下线,但是由于Eureka server的REST API有response cache,因此需要等待缓存过期才能更新
response-cache-auto-expiration-in-seconds: 60
client:
#eureka client刷新本地缓存时间 默认30s
registryFetchIntervalSeconds: 5
register-with-eureka: false
fetch-registry: false
serviceUrl:
defaultZone: http://127.0.0.1:${server.port}/eureka/
======================================================
log4j2.xml内容:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration xmlns:xi="http://www.w3.org/2001/XInclude" status="WARN">
<Properties>
<Property name="APPNAME">eureka</Property>
<Property name="LOGSDIR">/home/tomcat/logs</Property>
<Property name="PATTERN_LAYOUT">[%-5p] %d{yyyy-MM-dd HH:mm:ss.SSS}(%t:%c:%L): %m%n</Property>
</Properties>
<Appenders>
<Console name="STDOUT">
<PatternLayout pattern="${PATTERN_LAYOUT}"/>
</Console>
<RollingFile name="ROLLING" fileName="${LOGSDIR}/${APPNAME}/app-${APPNAME}.log" filePattern="${LOGSDIR}/${APPNAME}/app-${APPNAME}-%d{yyyy-MM-dd}-%i.log.gz">
<PatternLayout pattern="${PATTERN_LAYOUT}"/>
<Policies>
<TimeBasedTriggeringPolicy />
<SizeBasedTriggeringPolicy size="500 MB"/>
</Policies>
<DefaultRolloverStrategy max="50">
<Delete basePath="${LOGSDIR}/${APPNAME}" maxDepth="2">
<IfFileName glob="app-${APPNAME}-*.log.gz" />
<IfLastModified age="15d" />
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<loggers>
<root level="INFO">
<appenderRef ref="STDOUT"/>
<appenderRef ref="ROLLING"/>
</root>
<logger level="DEBUG" name="net.zkbc"/>
</loggers>
</Configuration>
===========================================================
pom.xml的内容,另外两个项目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.ecctest</groupId>
<artifactId>eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>eureka</name>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
<version>1.5.3.RELEASE</version>
<exclusions>
<exclusion>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<version>1.3.5.RELEASE</version>
<exclusions>
<exclusion>
<groupId>javax.servlet</groupId>
<artifactId>servlet-api</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<version>1.3.5.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-log4j2</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-mail</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-freemarker</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-sts</artifactId>
<version>1.11.125</version>
<exclusions>
<exclusion>
<groupId>commons-logging</groupId>
<artifactId>commons-logging</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-autoscaling</artifactId>
<version>1.11.125</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-ec2</artifactId>
<version>1.11.125</version>
</dependency>
<dependency>
<groupId>com.amazonaws</groupId>
<artifactId>aws-java-sdk-route53</artifactId>
<version>1.11.125</version>
</dependency>
<dependency>
<groupId>org.hdrhistogram</groupId>
<artifactId>HdrHistogram</artifactId>
<version>2.1.9</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-cbor</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.dataformat</groupId>
<artifactId>jackson-dataformat-xml</artifactId>
<version>2.8.8</version>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
<version>1.5.3.RELEASE</version>
</dependency>
<dependency>
<groupId>com.netflix.hystrix</groupId>
<artifactId>hystrix-core</artifactId>
<version>1.5.12</version>
</dependency>
<dependency>
<groupId>com.netflix.archaius</groupId>
<artifactId>archaius-core</artifactId>
<version>0.7.4</version>
</dependency>
<dependency>
<groupId>org.springframework.security</groupId>
<artifactId>spring-security-crypto</artifactId>
<version>4.2.2.RELEASE</version>
</dependency>
</dependencies>
</project>
=======================================================================
eFeignServer 项目:
启动类:
package eFeignServer;
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;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "eFeignServer")
@SpringBootApplication
@EnableDiscoveryClient
@EnableFeignClients
public class FeignServerApplication {
public static void main(String[] args) {
SpringApplication.run(FeignServerApplication.class, args);
}
}
=======================================================================
package eFeignServer;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
/**
* Created by cong on 2018/5/17.
*/
@RestController
public class ConsumerController {
@Autowired
FeignService feignService;
@RequestMapping("/consumer")
public String helloConsumer(){
return feignService.hello();
}
@RequestMapping("/consumer2")
public String helloConsumer2(){
String r1 = feignService.hello("hjc");
String r2 = feignService.hello("hjc", 23).toString();
String r3 = feignService.hello(new User("hjc", 23));
return r1 + "-----" + r2 + "----" + r3;
}
}
=================================================
package eFeignServer;
import org.springframework.stereotype.Component;
/**
* Created by cong on 2018/5/17.
*/
@Component
public class FeignFallBack implements FeignService{
//实现的方法是服务调用的降级方法
@Override
public String hello() {
return "errorhello";
}
@Override
public String hello(String name) {
return "error";
}
@Override
public User hello(String name, Integer age) {
return new User();
}
@Override
public String hello(User user) {
return "error";
}
}
=================================================
package eFeignServer;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.*;
/**
* Created by cong on 2018/5/17.
*/
//configuration = xxx.class 这个类配置Hystrix的一些精确属性
//value=“你用到的服务名称”
@FeignClient(value = "feign-consumer",fallback = FeignFallBack.class)
public interface FeignService {
//服务中方法的映射路径
@RequestMapping("/hello")
String hello();
@RequestMapping(value = "/hellol", method= RequestMethod.GET)
String hello(@RequestParam("name") String name) ;
@RequestMapping(value = "/hello2", method= RequestMethod.GET)
User hello(@RequestHeader("name") String name, @RequestHeader("age") Integer age);
@RequestMapping(value = "/hello3", method= RequestMethod.POST)
String hello(@RequestBody User user);
}
=================================================
package eFeignServer;
/**
* Created by cong 2017/12/2.
*/
public class User {
private String name;
private Integer age;
//序列化传输的时候必须要有空构造方法,不然会出错
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
==================================================
application.yml内容:
server:
port: 8083
spring:
application:
name: feign-server
eureka:
client:
service-url:
defaultZone: http://localhost:1112/eureka
feign:
hystrix:
enabled: true
ribbon:
eureka:
enabled: true
========================================================
eFeignClient只是一个普通rest服务,可以实现业务逻辑。
启动类:
package eFeignServer;
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;
import org.springframework.context.annotation.ComponentScan;
@ComponentScan(basePackages = "eFeignClient")
@SpringBootApplication
@EnableDiscoveryClient
//@EnableFeignClients
public class FeignApplication {
public static void main(String[] args) {
SpringApplication.run(FeignApplication.class, args);
}
}
===================================================================
package eFeignClient;
import java.util.ArrayList;
import java.util.List;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestHeader;
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;
/**
* Created by cong on 2018/5/8.
*/
@RestController
public class HelloController {
@RequestMapping("/hello")
public String hello(){
System.out.println("访问来1了......");
return "hello1";
}
@RequestMapping("/hjcs")
public List<String> laowangs(String ids){
List<String> list = new ArrayList<>();
list.add("laowang1");
list.add("laowang2");
list.add("laowang3");
return list;
}
//新增的方法
@RequestMapping(value = "/hellol", method= RequestMethod.GET)
public String hello(@RequestParam String name) {
return "Hello " + name;
}
@RequestMapping(value = "/hello2", method= RequestMethod.GET)
public User hello(@RequestHeader String name, @RequestHeader Integer age) {
return new User(name, age);
}
@RequestMapping(value = "/hello3", method = RequestMethod.POST)
public String hello (@RequestBody User user) {
return "Hello "+ user. getName () + ", " + user. getAge ();
}
}
===========================================================
奇怪的是,业务数据类居然不需要序列化???
package eFeignClient;
/**
* Created by cong 2017/12/2.
*/
public class User {
private String name;
private Integer age;
//序列化传输的时候必须要有空构造方法,不然会出错
public User() {
}
public User(String name, Integer age) {
this.name = name;
this.age = age;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Integer getAge() {
return age;
}
public void setAge(Integer age) {
this.age = age;
}
}
===================================================================
application.yml内容:
server:
port: 8084
spring:
application:
name: feign-consumer
eureka:
client:
service-url:
defaultZone: http://localhost:1112/eureka
feign:
hystrix:
enabled: true
ribbon:
eureka:
enabled: true
================================================
启动三个项目的启动类,访问本地注册中心http://localhost:1112/,应该可以看到注册中心有两个服务已经运行了。
后面访问rest服务,地址:http://localhost:8084/hello
可以看到页面显示:
访问FeignClien功能的远程调用服务,地址:http://localhost:8083/consumer
停止eFeignClient服务,再次访问FeignClien功能的远程调用服务,地址:http://localhost:8083/consumer
可以看到FallBack的页面效果