服务网关-Zuul路由的各种姿势

This commit is contained in:
fengyongwei
2017-11-27 12:13:51 +08:00
parent e36e028616
commit e8f19dc2ee
39 changed files with 1413 additions and 0 deletions

9
spring-cloud-23/.gitignore vendored Normal file
View File

@@ -0,0 +1,9 @@
*/target/
*.project
*.classpath
*.project
*.settings
*.mvn
*.project
*.springBeans
*.bin

88
spring-cloud-23/pom.xml Normal file
View File

@@ -0,0 +1,88 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
<packaging>pom</packaging>
<name>spring-cloud-23</name>
<description>roncoo-spring-cloud project for Spring Boot</description>
<modules>
<module>spring-cloud-bean-23</module>
<module>spring-cloud-api-23</module>
<module>spring-cloud-consumer-23</module>
<module>spring-cloud-provider-23</module>
<module>spring-cloud-service-23</module>
<module>spring-cloud-turbine-23</module>
<module>spring-cloud-gateway-23</module>
</modules>
<!-- <parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>1.5.2.RELEASE</version>
<relativePath />
</parent> -->
<!-- http://platform.spring.io/platform/ -->
<parent>
<groupId>io.spring.platform</groupId>
<artifactId>platform-bom</artifactId>
<version>Brussels-SR1</version>
<relativePath/>
</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>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-bean-23</artifactId>
<version>${project.version}</version>
</dependency>
<dependency>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-api-23</artifactId>
<version>${project.version}</version>
</dependency>
<!-- spring cloud -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>Camden.SR6</version>
<!-- <version>Dalston.BUILD-SNAPSHOT</version> -->
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<repositories>
<repository>
<id>spring-snapshots</id>
<name>Spring Snapshots</name>
<url>https://repo.spring.io/snapshot</url>
<snapshots>
<enabled>true</enabled>
</snapshots>
</repository>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
<snapshots>
<enabled>false</enabled>
</snapshots>
</repository>
</repositories>
</project>

View File

@@ -0,0 +1,29 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-api-23</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-api-23</name>
<description>spring-cloud project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-bean-23</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,16 @@
package com.roncoo.education.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
* @author wujing
*/
@FeignClient(value = "roncoo", url = "www.roncoo.com")
public interface IRoncooBiz {
@RequestMapping(value = "/{url}", method = RequestMethod.GET)
String get(@PathVariable(name = "url") String url);
}

View File

@@ -0,0 +1,53 @@
package com.roncoo.education.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.roncoo.education.feign.configuration.RcFeignConfiguration;
import com.roncoo.education.feign.fallback.RcFeignFallback;
import com.roncoo.education.service.UserService;
/**
* @author wujing
*/
@FeignClient(value = "spring-cloud-provider", configuration = RcFeignConfiguration.class, fallback=RcFeignFallback.class)
public interface IUserBiz extends UserService{
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET)
String view1(@PathVariable(name = "id") int id);
//说明method需要指定
//@RequestLine("GET /api/user/{id}")
//String view1(@Param(value = "id") int id);
//@GetMapping(value = "/api/user/{id}")
//String view1(@PathVariable(name = "id") int id);
// 不支持该方式传值,启动出错。
//@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET)
//User get3(@PathVariable(value = "id") int id, @RequestParam String name);
/*@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET)
User get4(@PathVariable(value = "id") int id, @RequestParam Map<String, Object> name);
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET)
User get5(@PathVariable(value = "id") int id, @RequestParam(value = "name") String name);
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET)
User get1(@PathVariable(value = "id") int id, String name);
@RequestMapping(value = "/api/user/get/{id}", method = RequestMethod.GET)
User get2(@PathVariable(value = "id") int id, Map<String, Object> name);
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET)
User view(@PathVariable(value = "id") int id);
//@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET)
//String view1(@PathVariable(value = "id") int id);
@RequestMapping(value = "/api/user/{id}", method = RequestMethod.GET)
Map<String, Object> view2(@PathVariable(value = "id") int id);*/
}

View File

@@ -0,0 +1,47 @@
package com.roncoo.education.feign.configuration;
import java.lang.reflect.Method;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Scope;
import com.netflix.hystrix.HystrixCommand;
import com.netflix.hystrix.HystrixCommand.Setter;
import com.netflix.hystrix.HystrixCommandGroupKey;
import com.netflix.hystrix.HystrixCommandKey;
import feign.Feign;
import feign.Logger;
import feign.Target;
import feign.hystrix.HystrixFeign;
import feign.hystrix.SetterFactory;
//@Configuration
public class RcFeignConfiguration {
@Bean
public Logger.Level feignLoggerLevel() {
return feign.Logger.Level.FULL;
}
/*@Bean
public Contract feignContract() {
return new feign.Contract.Default();
}*/
@Bean
@Scope("prototype")
public Feign.Builder feignBuilder() {
class RcSetterFactory implements SetterFactory {
@Override
public Setter create(Target<?> target, Method method) {
String groupKey = target.name();
String commandKey = method.getName();
return HystrixCommand.Setter.withGroupKey(HystrixCommandGroupKey.Factory.asKey(groupKey))
.andCommandKey(HystrixCommandKey.Factory.asKey(commandKey));
}
}
return HystrixFeign.builder().setterFactory(new RcSetterFactory());
// return Feign.builder();
}
}

View File

@@ -0,0 +1,19 @@
package com.roncoo.education.feign.fallback;
import org.springframework.stereotype.Component;
import com.roncoo.education.bean.User;
import com.roncoo.education.feign.IUserBiz;
@Component
public class RcFeignFallback implements IUserBiz {
@Override
public User find(int id) {
return null;
}
@Override
public String view1(int id) {
System.out.println("调用远程接口异常,返回自定义信息");
return "system error";
}
}

View File

@@ -0,0 +1,25 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-bean-23</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-bean-23</name>
<description>spring-cloud project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,44 @@
package com.roncoo.education.bean;
import java.util.Date;
/**
* 实体类
*
* @author wujing
*/
public class User {
private int id;
private String name;
private Date createTime;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Date getCreateTime() {
return createTime;
}
public void setCreateTime(Date createTime) {
this.createTime = createTime;
}
@Override
public String toString() {
return "RoncooUser [id=" + id + ", name=" + name + ", createTime=" + createTime + "]";
}
}

View File

@@ -0,0 +1,13 @@
package com.roncoo.education.service;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import com.roncoo.education.bean.User;
public interface UserService {
@RequestMapping(method = RequestMethod.GET, value = "/api/user/find/{id}")
User find(@PathVariable(value = "id") int id);
}

View File

@@ -0,0 +1,67 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-consumer-23</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-consumer-23</name>
<description>spring-cloud project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
</dependency>
<dependency>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-api-23</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,27 @@
package com.roncoo.education;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
@EnableCircuitBreaker
@EnableFeignClients
@EnableEurekaClient
@SpringBootApplication
public class ConsumerApplication {
@Bean
@LoadBalanced
protected RestTemplate restTemplate() {
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
}

View File

@@ -0,0 +1,9 @@
//package com.roncoo.education.configuration;
//import org.springframework.cloud.netflix.ribbon.RibbonClient;
//import org.springframework.context.annotation.Configuration;
//
//@Configuration
//@RibbonClient(name = "spring-cloud-provider2", configuration = RoundRobinRuleConfig.class)
//public class Provider2Configuration {
//
//}

View File

@@ -0,0 +1,10 @@
//package com.roncoo.education.configuration;
//
//import org.springframework.cloud.netflix.ribbon.RibbonClient;
//import org.springframework.context.annotation.Configuration;
//
//@Configuration
//@RibbonClient(name = "spring-cloud-provider", configuration = RandomRuleConfig.class)
//public class ProviderConfiguration {
//
//}

View File

@@ -0,0 +1,18 @@
//package com.roncoo.education.configuration;
//import org.springframework.context.annotation.Bean;
//import org.springframework.context.annotation.Configuration;
//import com.netflix.loadbalancer.IRule;
//import com.netflix.loadbalancer.RandomRule;
//
///**
// * 随机算法
// *
// * @author wujing
// */
////@Configuration
//public class RandomRuleConfig {
// @Bean
// public IRule randomRule() {
// return new RandomRule();
// }
//}

View File

@@ -0,0 +1,64 @@
package com.roncoo.education.configuration;
import java.util.List;
import com.netflix.client.config.IClientConfig;
import com.netflix.loadbalancer.AbstractLoadBalancerRule;
import com.netflix.loadbalancer.ILoadBalancer;
import com.netflix.loadbalancer.Server;
/**
* 自定义Ribbon的负载均衡策略
*
*/
public class RoncooCustomRule extends AbstractLoadBalancerRule {
private Server choose(ILoadBalancer lb, Object key) {
if (lb == null) {
return null;
}
Server server = null;
while (server == null) {
if (Thread.interrupted()) {
return null;
}
List<Server> upList = lb.getReachableServers(); // 可用的服务实例
// 只获取端口为7779的服务实例
for (Server s : upList) {
if (s.getPort() == 7779) {
server = s;
}
}
if (server == null) {
Thread.yield();
continue;
}
System.out.println("实例IP" + server.getHost() + " 端口:" + server.getPort());
if (server.isAlive()) {
return (server);
}
server = null;
Thread.yield();
}
return server;
}
@Override
public Server choose(Object key) {
return choose(getLoadBalancer(), key);
}
@Override
public void initWithNiwsConfig(IClientConfig clientConfig) {
// TODO Auto-generated method stub
}
}

View File

@@ -0,0 +1,17 @@
//package com.roncoo.education.configuration;
//import org.springframework.context.annotation.Bean;
//import com.netflix.loadbalancer.IRule;
//import com.netflix.loadbalancer.RandomRule;
//import com.netflix.loadbalancer.RoundRobinRule;
///**
// * 轮询算法
// *
// * @author wujing
// */
//// @Configuration
//public class RoundRobinRuleConfig {
// @Bean
// public IRule roundRobinRule() {
// return new RandomRule();
// }
//}

View File

@@ -0,0 +1,39 @@
package com.roncoo.education.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import com.roncoo.education.feign.IRoncooBiz;
import com.roncoo.education.feign.IUserBiz;
/**
* @author wujing
*/
@RestController
@RequestMapping(value = "/feign/user", method = RequestMethod.POST)
public class FeignUserController {
@Autowired
private IUserBiz userBiz;
@Autowired
private IRoncooBiz roncooBiz;
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String get(@PathVariable(value = "id") int id) {
//System.out.println(userBiz.view(id));
//System.out.println(userBiz.view1(id));
//System.out.println(userBiz.view2(id));
//String name = "测试1";
//Map<String, Object> map = new HashMap<>();
//map.put("name", "测试2");
//userBiz.get4(id, map);
//userBiz.get5(id, name);
//System.out.println(roncooBiz.get("course/list.html"));
//System.out.println(userBiz.find(id));
return userBiz.view1(id);
}
}

View File

@@ -0,0 +1,47 @@
package com.roncoo.education.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixProperty;
import com.netflix.hystrix.contrib.javanica.conf.HystrixPropertiesManager;
/**
* @author wujing
*/
@RestController
@RequestMapping(value = "/user", method = RequestMethod.POST)
public class UserController {
// private static final String URL="http://localhost:7777/api/user/{id}";
private static final String URL = "http://spring-cloud-provider/api/user/{id}";
private static final String URL2 = "http://spring-cloud-provider2/api/user/{id}";
@Autowired
private RestTemplate restTemplate;
@HystrixCommand(fallbackMethod = "getFallback", commandProperties = @HystrixProperty(name = HystrixPropertiesManager.EXECUTION_ISOLATION_STRATEGY, value = "SEMAPHORE"))
//@HystrixCommand(fallbackMethod = "getFallback", commandKey="", groupKey="")
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public String get(@PathVariable(value = "id") int id) {
//throw new RuntimeException();
return restTemplate.getForObject(URL, String.class, id);
}
public String getFallback(int id) {
System.out.println("调用远程接口异常,返回自定义信息");
return "自定义信息";
}
@RequestMapping(value = "/2/{id}", method = RequestMethod.GET)
public String get2(@PathVariable(value = "id") int id) {
return restTemplate.getForObject(URL2, String.class, id);
}
}

View File

@@ -0,0 +1,56 @@
# server
server.port=8888
# spring
spring.application.name=spring-cloud-consumer
# eureka
#eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.serviceUrl.defaultZone=http://roncoo:123456@localhost:8761/eureka/
# info自定义
info.build.name=@project.name@
info.build.description=@project.description@
info.build.groupId=@project.groupId@
info.build.artifact=@project.artifactId@
info.build.version=@project.version@
eureka.instance.status-page-url-path=/info
eureka.instance.instanceId=${spring.application.name}:${random.value}
eureka.instance.prefer-ip-address=true
#设置拉取服务注册信息时间默认60s
eureka.client.registry-fetch-interval-seconds=30
#指定续约更新频率默认是30s
eureka.instance.lease-renewal-interval-in-seconds=15
#设置过期剔除时间默认90s
eureka.instance.lease-expiration-duration-in-seconds=45
#设置策略
spring-cloud-provider.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
spring-cloud-provider2.ribbon.NFLoadBalancerRuleClassName=com.netflix.loadbalancer.RandomRule
#spring-cloud-provider.ribbon.NFLoadBalancerRuleClassName=com.roncoo.education.configuration.RoncooCustomRule
#格式为:应用名.ribbon.NFLoadBalancerRuleClassName=xxx
# 日志配置,默认是不打印任何的日志
logging.level.com.roncoo.education.feign=debug
# 开启压缩
feign.compression.request.enabled=true
feign.compression.response.enabled=true
# 更多配置
feign.compression.request.mime-types=text/xml,application/xml,application/json
feign.compression.request.min-request-size=2048
# 在feign里面禁用hystrix
#feign.hystrix.enabled=false
# 在feign和Ribbon里面配置隔离策略全局配置
#hystrix.command.default.execution.isolation.strategy=SEMAPHORE
# 配置单个
#hystrix.command.view1.execution.isolation.strategy=SEMAPHORE
# 元数据
eureka.instance.metadata-map.cluster=RONCOO

View File

@@ -0,0 +1,16 @@
package com.roncoo.education;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ConsumerApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@@ -0,0 +1,25 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-gateway-23</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-zuul</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,35 @@
package com.roncoo.education;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
import org.springframework.context.annotation.Bean;
import com.roncoo.education.custom.CustomPreFilter;
@EnableZuulProxy
@SpringBootApplication
public class GatewayApplication {
@Bean
public CustomPreFilter sessionPreFilter() {
return new CustomPreFilter();
}
/*@Bean
public PatternServiceRouteMapper serviceRouteMapper() {
return new PatternServiceRouteMapper("(?<name1>^.*)-(?<name2>c.*)-(?<name3>c.+$)", "${name1}-${name2}-provider") {
@Override
public String apply(final String serviceId) {
String route = super.apply(serviceId);
System.out.println(route + " -> " + serviceId);
return route;
}
};
}*/
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}

View File

@@ -0,0 +1,51 @@
package com.roncoo.education.custom;
import java.io.IOException;
import java.io.PrintWriter;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.util.ReflectionUtils;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
public class CustomPreFilter extends ZuulFilter {
@Override
public String filterType() {
return "pre";
}
@Override
public int filterOrder() {
return 1;
}
@Override
public boolean shouldFilter() {
return true;
}
@Override
public Object run() {
RequestContext ctx = RequestContext.getCurrentContext();
HttpServletRequest request = ctx.getRequest();
String token = request.getHeader("token");
if (!"roncoo".equals(token)) {
HttpServletResponse response = ctx.getResponse();
try {
PrintWriter writer = response.getWriter();
writer.println("token is error");
writer.close();
} catch (IOException e) {
ReflectionUtils.rethrowRuntimeException(e);
}
}
System.out.println("请求路径为:" + request.getRequestURI());
return null;
}
}

View File

@@ -0,0 +1,59 @@
package com.roncoo.education.custom;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import org.springframework.cloud.netflix.zuul.filters.route.ZuulFallbackProvider;
import org.springframework.http.HttpHeaders;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.http.client.ClientHttpResponse;
import org.springframework.stereotype.Component;
@Component
public class ProviderFallbackProvider implements ZuulFallbackProvider {
@Override
public String getRoute() {
return "spring-cloud-provider";
}
@Override
public ClientHttpResponse fallbackResponse() {
return new ClientHttpResponse() {
@Override
public HttpStatus getStatusCode() throws IOException {
return HttpStatus.OK;
}
@Override
public int getRawStatusCode() throws IOException {
return 200;
}
@Override
public String getStatusText() throws IOException {
return "OK";
}
@Override
public void close() {
}
@Override
public InputStream getBody() throws IOException {
return new ByteArrayInputStream((getRoute()+ " is fallback").getBytes());
}
@Override
public HttpHeaders getHeaders() {
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
return headers;
}
};
}
}

View File

@@ -0,0 +1,92 @@
# server
server.port=9876
# spring
spring.application.name=spring-cloud-gateway
# eureka
#eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.serviceUrl.defaultZone=http://roncoo:123456@localhost:8761/eureka/
# info自定义
info.build.name=@project.name@
info.build.description=@project.description@
info.build.groupId=@project.groupId@
info.build.artifact=@project.artifactId@
info.build.version=@project.version@
eureka.instance.status-page-url-path=/info
eureka.instance.instanceId=${spring.application.name}:${random.value}
eureka.instance.prefer-ip-address=true
#设置拉取服务注册信息时间默认60s
eureka.client.registry-fetch-interval-seconds=30
#指定续约更新频率默认是30s
eureka.instance.lease-renewal-interval-in-seconds=15
#设置过期剔除时间默认90s
eureka.instance.lease-expiration-duration-in-seconds=45
# zuul.<SimpleClassName>.<filterType>.disable=true
# 禁用自定义过滤器
zuul.CustomPreFilter.pre.disable=true
# 路由的映射方法1
#zuul.routes.spring-cloud-provider=/provider/**
#zuul.routes.spring-cloud-consumer=/consumer/**
# spring-cloud-provider服务名称对其进行路由
# 一个*代表匹配一层,二个**代表匹配所有。
# 路由的映射方法2
#zuul.routes.provider1.path=/provider1/**
#zuul.routes.provider1.service-id=spring-cloud-provider
#zuul.routes.consumer1.path=/consumer1/**
#zuul.routes.consumer1.service-id=spring-cloud-consumer
# provider1,consumer2 代表id随意不重复即可
logging.level.com.netflix.loadbalancer=debug
#zuul.ignored-services=spring-cloud-provider
# 注意: zuul.ignored-services=* 禁用所有
zuul.routes.provider1.strip-prefix=false
zuul.routes.provider1.path=/api/**
zuul.routes.provider1.service-id=spring-cloud-provider
zuul.routes.consumer1.strip-prefix=false
zuul.routes.consumer1.path=/feign/**
zuul.routes.consumer1.service-id=spring-cloud-consumer
#zuul.routes.provider1.sensitive-headers=token
#zuul.routes.spring-cloud-provider.sensitive-headers=token
# 默认值Cookie,Set-Cookie,Authorization
# 注意:如果不禁用服务名的情况下,通过服务名,这个设置是无效的
# zuul.routes.spring-cloud-provider 这种配置的情况下,也是无效的
# 禁用注册中心
#ribbon.eureka.enabled=false
#zuul.routes.roncoo.path=/**
#zuul.routes.roncoo.url=http://www.roncoo.com/
#zuul.routes.roncoo.path=/**
#zuul.routes.roncoo.service-id=roncoo-education
#roncoo-education.ribbon.listOfServers=http://www.roncoo.com/,http://git.oschina.net/
zuul.ignored-patterns=/**/feign/**
# 忽略含有api的路径的url
#zuul.routes.legacy.path=/**
#zuul.routes.legacy.url=http://www.roncoo.com
# 若前面的路由匹配不到,那么就使用这个
hystrix.command.default.execution.isolation.thread.timeoutInMilliseconds=60000
# 全局设置
ribbon.ConnectTimeout=60000
ribbon.ReadTimeout=60000

View File

@@ -0,0 +1,62 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-provider-23</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-provider-23</name>
<description>spring-cloud project for Spring Boot</description>
<dependencies>
<dependency>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-bean-23</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-actuator</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,14 @@
package com.roncoo.education;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@EnableEurekaClient
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
SpringApplication.run(ProviderApplication.class, args);
}
}

View File

@@ -0,0 +1,64 @@
package com.roncoo.education.controller;
import java.io.File;
import java.io.IOException;
import java.util.Date;
import javax.servlet.http.HttpServletRequest;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.FileCopyUtils;
import org.springframework.web.bind.annotation.PathVariable;
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.RequestParam;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.multipart.MultipartFile;
import com.roncoo.education.bean.User;
/**
* @author wujing
*/
@RestController
@RequestMapping(value = "/api/user")
public class ApiUserController {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@RequestMapping(value = "/get/{id}")
public User get(@PathVariable int id, @RequestBody(required = false) String json,
@RequestParam(required = false) String name, HttpServletRequest request) {
logger.info("请求方法类型:" + request.getMethod() + " RequestBody参数" + json + " RequestParam参数" + name);
User user = new User();
user.setId(id);
user.setName("无境");
user.setCreateTime(new Date());
// logger.info("请求接口返回:{}", user);
return user;
}
@RequestMapping(value = "/{id}", method = RequestMethod.GET)
public User view(@PathVariable int id, HttpServletRequest request) throws InterruptedException {
//Thread.sleep(50000);
User user = new User();
user.setId(id);
user.setName("无境1");
user.setCreateTime(new Date());
logger.info("请求接口返回:{}", user);
System.out.println("通过zuul获取的token=" + request.getHeader("token"));
return user;
}
@RequestMapping(value = "/upload")
public String upload(@RequestParam(value = "file") MultipartFile file) throws IOException {
File out = new File("D:/" + file.getOriginalFilename());
FileCopyUtils.copy(file.getBytes(), out);
return "sucess";
}
}

View File

@@ -0,0 +1,31 @@
package com.roncoo.education.controller;
import java.util.Date;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import com.roncoo.education.bean.User;
import com.roncoo.education.service.UserService;
/**
* @author wujing
*/
@RestController
public class FeignApiUserController implements UserService {
protected final Logger logger = LoggerFactory.getLogger(this.getClass());
@Override
public User find(@PathVariable int id) {
User user = new User();
user.setId(id);
user.setName("无境1");
user.setCreateTime(new Date());
logger.info("请求接口返回:{}", user);
return user;
}
}

View File

@@ -0,0 +1,33 @@
# server
server.port=7778
# spring
spring.application.name=spring-cloud-provider
# eureka
#eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.serviceUrl.defaultZone=http://roncoo:123456@localhost:8761/eureka/
# info自定义
info.build.name=@project.name@
info.build.description=@project.description@
info.build.groupId=@project.groupId@
info.build.artifact=@project.artifactId@
info.build.version=@project.version@
eureka.instance.status-page-url-path=/info
eureka.instance.instanceId=${spring.application.name}:${random.value}
eureka.instance.prefer-ip-address=true
#设置拉取服务注册信息时间默认60s
eureka.client.registry-fetch-interval-seconds=30
#指定续约更新频率默认是30s
eureka.instance.lease-renewal-interval-in-seconds=15
#设置过期剔除时间默认90s
eureka.instance.lease-expiration-duration-in-seconds=45
spring.http.multipart.max-file-size=1000MB
spring.http.multipart.max-request-size=1000MB

View File

@@ -0,0 +1,16 @@
package com.roncoo.education;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ProviderApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@@ -0,0 +1,61 @@
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-service-23</artifactId>
<packaging>jar</packaging>
<name>spring-cloud-service-23</name>
<description>spring-cloud project for Spring Boot</description>
<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-security</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-devtools</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix-dashboard</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
<configuration>
<executable>true</executable>
</configuration>
</plugin>
</plugins>
</build>
</project>

View File

@@ -0,0 +1,16 @@
package com.roncoo.education;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
import org.springframework.cloud.netflix.hystrix.dashboard.EnableHystrixDashboard;
@EnableHystrixDashboard
@EnableEurekaServer
@SpringBootApplication
public class ServiceApplication {
public static void main(String[] args) {
SpringApplication.run(ServiceApplication.class, args);
}
}

View File

@@ -0,0 +1,43 @@
# server (eureka 默认端口为8761)
server.port=8761
# spring
spring.application.name=spring-cloud-server
# eureka
# 是否注册到eureka
eureka.client.register-with-eureka=false
# 是否从eureka获取注册信息
eureka.client.fetch-registry=false
# eureka服务器的地址注意地址最后面的 /eureka/ 这个是固定值)
#eureka.client.serviceUrl.defaultZone=http://localhost:${server.port}/eureka/
eureka.client.serviceUrl.defaultZone=http://roncoo:123456@localhost:8761/eureka/
eureka.client.availability-zones.roncoo=roncooZone
eureka.client.service-url.roncooZone=http://roncoo:123456@localhost:8761/eureka/
eureka.client.region=lll
# info自定义
info.build.name=@project.name@
info.build.description=@project.description@
info.build.groupId=@project.groupId@
info.build.artifact=@project.artifactId@
info.build.version=@project.version@
# 指定环境
eureka.environment=dev
#指定数据中心
eureka.datacenter=roncoo
# 关闭自我保护模式
eureka.server.enable-self-preservation=false
#设置清理无效节点的时间间隔默认60000即是60s
eureka.server.eviction-interval-timer-in-ms=5000
# 服务认证
security.basic.enabled=true
security.user.name=roncoo
security.user.password=123456

View File

@@ -0,0 +1,16 @@
package com.roncoo.education;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.springframework.boot.test.context.SpringBootTest;
import org.springframework.test.context.junit4.SpringRunner;
@RunWith(SpringRunner.class)
@SpringBootTest
public class ServiceApplicationTests {
@Test
public void contextLoads() {
}
}

View File

@@ -0,0 +1,26 @@
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2301/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>
<groupId>com.roncoo.education</groupId>
<artifactId>spring-cloud-23</artifactId>
<version>0.0.1-SNAPSHOT</version>
</parent>
<artifactId>spring-cloud-turbine-23</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-turbine</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-actuator</artifactId>
</dependency>
</dependencies>
</project>

View File

@@ -0,0 +1,14 @@
package com.roncoo.education;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.turbine.EnableTurbine;
@EnableTurbine
@SpringBootApplication
public class TurbineApplication {
public static void main(String[] args) {
SpringApplication.run(TurbineApplication.class, args);
}
}

View File

@@ -0,0 +1,42 @@
# server
server.port=9999
# spring
spring.application.name=spring-cloud-turbine
# eureka
#eureka.client.serviceUrl.defaultZone=http://localhost:8761/eureka/
eureka.client.serviceUrl.defaultZone=http://roncoo:123456@localhost:8761/eureka/
# info自定义
info.build.name=@project.name@
info.build.description=@project.description@
info.build.groupId=@project.groupId@
info.build.artifact=@project.artifactId@
info.build.version=@project.version@
eureka.instance.status-page-url-path=/info
eureka.instance.instanceId=${spring.application.name}:${random.value}
eureka.instance.prefer-ip-address=true
#设置拉取服务注册信息时间默认60s
eureka.client.registry-fetch-interval-seconds=30
#指定续约更新频率默认是30s
eureka.instance.lease-renewal-interval-in-seconds=15
#设置过期剔除时间默认90s
eureka.instance.lease-expiration-duration-in-seconds=45
# turbine说明注意必须为大写因为eureka返回的值都是大写的
#turbine.aggregator.clusterConfig=SPRING-CLOUD-CONSUMER
#turbine.app-config=spring-cloud-consumer
#turbine.aggregator.clusterConfig=RONCOO
#turbine.app-config=spring-cloud-consumer,spring-cloud-consumer2
#turbine.cluster-name-expression=metadata['cluster']
#turbine.combine-host-port=true
# turbine.aggregator.clusterConfig=RONCOO
turbine.app-config=spring-cloud-consumer,spring-cloud-consumer2
turbine.cluster-name-expression='default'