提交 67e9f5b8 编写于 作者: 武汉红喜's avatar 武汉红喜

Finchley

上级 4d352434
......@@ -25,7 +25,7 @@ whatsmars-sharding-jdbc | 开源分布式数据库中间件
whatsmars-spring | spring原理、集成及新特性
whatsmars-spring-boot | springboot实战
whatsmars-spring-boot-samples | 常用starters样例
whatsmars-spring-cloud | springcloud demo
whatsmars-spring-cloud | Finchley
whatsmars-tomcat | 模拟tomcat实现,embed tomcat
[spring-boot-latest](https://github.com/javahongxi/spring-boot-latest) | Spring 5+, Spring Boot 2+
[spring-boot-simple](https://github.com/javahongxi/spring-boot-simple) | the simplest boot
......
https://github.com/spring-cloud/spring-cloud-netflix
# Spring Cloud
`Finchley`
依次启动eureka,provider,consumer,zuul
依次启动eureka,provider,consumer
1. 直接访问 localhost:8763/hi?name=hongxi
1. 网关访问 localhost:8764/demo/hi?name=hongxi&accessToken=123456 localhost:8764/demo/hi?name=hongxi
1. 停掉provider,再次进行上面的访问
API网关(zuul)
1. 通过 API 网关,封装微服务的 REST API。
1. 均通过 API 网关 进行调用,享受 API 网关带来的统一鉴权,统一监控等好处。
1. 通过 API 网关,控制对外暴露的 API,减轻安全隐患。
https://github.com/spring-cloud/spring-cloud-netflix
https://github.com/spring-cloud-samples
\ No newline at end of file
......@@ -3,36 +3,37 @@
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>whatsmars-parent</artifactId>
<groupId>org.hongxi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<groupId>org.hongxi</groupId>
<artifactId>whatsmars-spring-cloud</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>pom</packaging>
<name>${project.artifactId}</name>
<description>The demo module of spring cloud project</description>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.5.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<modules>
<module>whatsmars-cloud-consumer</module>
<module>whatsmars-cloud-eureka</module>
<module>whatsmars-cloud-provider</module>
<module>whatsmars-cloud-zuul</module>
</modules>
<properties>
<spring-cloud.version>Edgware.RELEASE</spring-cloud.version>
<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>Finchley.RELEASE</spring-cloud.version>
</properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-dependencies</artifactId>
<version>${spring-boot.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
......@@ -44,6 +45,14 @@
</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>
......@@ -54,4 +63,13 @@
</repository>
</repositories>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
......@@ -21,62 +21,21 @@
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-feign</artifactId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-hystrix</artifactId>
<artifactId>spring-cloud-starter-netflix-hystrix</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-test</artifactId>
<scope>test</scope>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>${springloaded.version}</version>
</dependency>
</dependencies>
<!-- POM不是继承spring-boot-starter-parent的话,需要下面的指定 -->
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
......@@ -4,10 +4,7 @@ import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.client.circuitbreaker.EnableCircuitBreaker;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.cloud.netflix.feign.EnableFeignClients;
import org.springframework.context.annotation.Bean;
import org.springframework.web.client.RestTemplate;
import org.springframework.cloud.openfeign.EnableFeignClients;
/**
* Created by shenhongxi on 2017/9/14.
......@@ -20,10 +17,4 @@ public class ConsumerApplication {
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
package org.hongxi.whatsmars.cloud.consumer.controller;
import org.hongxi.whatsmars.cloud.consumer.feign.DemoFeign;
import org.hongxi.whatsmars.cloud.consumer.rpc.DemoRpc;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
/**
* Created by shenhongxi on 2017/9/14.
......@@ -12,19 +12,11 @@ import org.springframework.web.bind.annotation.RestController;
@RestController
public class DemoController {
@Autowired
private DemoRpc demoRpc;
@Autowired
private DemoFeign demoFeign;
@RequestMapping("/hello")
public String hello(String name) {
return demoRpc.hello(name);
}
@RequestMapping("/hi")
public String hi(String name) {
return demoFeign.hello(name);
public Mono<String> hi(String name) {
return Mono.just(demoFeign.hello(name));
}
}
package org.hongxi.whatsmars.cloud.consumer.feign;
import org.springframework.cloud.netflix.feign.FeignClient;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
/**
* Created by shenhongxi on 2017/9/14.
*/
@FeignClient(value = "${provider.name}", fallback = DemoHystrix.class)
@FeignClient(value = "demo-provider", fallback = DemoHystrix.class)
public interface DemoFeign {
@RequestMapping("/hello")
String hello(@RequestParam(name = "name") String name); // 此处必须有RequestParam
......
package org.hongxi.whatsmars.cloud.consumer.rpc;
import com.netflix.hystrix.contrib.javanica.annotation.HystrixCommand;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;
import org.springframework.web.client.RestTemplate;
/**
* Created by javahongxi on 2017/12/28.
*/
@Component
public class DemoRpc {
@Autowired
private RestTemplate restTemplate;
@Autowired
private Environment env;
@HystrixCommand(fallbackMethod = "helloFallback")
public String hello(String name) {
return restTemplate.getForObject("http://" + env.getProperty("provider.name") + "/hello?name=" + name, String.class);
}
public String helloFallback(String name) {
return "Hi, " + name + ", Here is Fallback";
}
}
spring:
profiles:
active: dev
provider:
name: demo-provider
---
eureka:
client:
serviceUrl:
defaultZone: http://test.toutiao.im:8761/eureka/
server:
port: 8763
spring:
application:
name: demo-consumer
profiles: test
feign:
hystrix:
enabled: true
---
eureka:
client:
serviceUrl:
service-url:
defaultZone: http://localhost:8761/eureka/
server:
port: 8763
spring:
application:
name: demo-consumer
profiles: dev
feign:
hystrix:
enabled: true
\ No newline at end of file
......@@ -19,50 +19,8 @@
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka-server</artifactId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>${springloaded.version}</version>
</dependency>
</dependencies>
<!-- POM不是继承spring-boot-starter-parent的话,需要下面的指定 -->
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
spring:
profiles:
active: dev
---
spring:
profiles: test
server:
port: 8761
eureka:
instance:
hostname: test.toutiao.im
client:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
# defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
defaultZone: http://test.toutiao.im:8761/eureka/
---
spring:
profiles: dev
server:
port: 8761
eureka:
instance:
hostname: localhost
......@@ -31,4 +7,4 @@ eureka:
registerWithEureka: false
fetchRegistry: false
serviceUrl:
defaultZone: http://localhost:8761/eureka/
\ No newline at end of file
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
\ No newline at end of file
......@@ -19,50 +19,13 @@
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-eureka</artifactId>
<artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<artifactId>spring-boot-starter-webflux</artifactId>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>${springloaded.version}</version>
</dependency>
</dependencies>
<!-- POM不是继承spring-boot-starter-parent的话,需要下面的指定 -->
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.cloud.provider;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.boot.builder.SpringApplicationBuilder;
import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
/**
......@@ -11,6 +11,6 @@ import org.springframework.cloud.client.discovery.EnableDiscoveryClient;
@SpringBootApplication
public class ProviderApplication {
public static void main(String[] args) {
new SpringApplicationBuilder(ProviderApplication.class).web(true).run(args);
SpringApplication.run(ProviderApplication.class, args);
}
}
......@@ -3,6 +3,7 @@ package org.hongxi.whatsmars.cloud.provider.service;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import reactor.core.publisher.Mono;
/**
* Created by shenhongxi on 2017/9/14.
......@@ -13,7 +14,7 @@ public class DemoService {
private String port;
@RequestMapping("/hello")
public String hello(String name) {
return "Hi, " + name + ", Here is " + port;
public Mono<String> hello(String name) {
return Mono.just("Hi, " + name + ", Here is " + port);
}
}
spring:
profiles:
active: dev
---
eureka:
client:
serviceUrl:
defaultZone: http://test.toutiao.im:8761/eureka/
server:
port: 8762
spring:
application:
name: demo-provider
profiles: test
---
eureka:
client:
serviceUrl:
......@@ -23,5 +6,4 @@ server:
port: 8762
spring:
application:
name: demo-provider
profiles: dev
name: demo-provider
\ No newline at end of file
<?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>whatsmars-spring-cloud</artifactId>
<groupId>org.hongxi</groupId>
<version>1.0-SNAPSHOT</version>
</parent>
<modelVersion>4.0.0</modelVersion>
<artifactId>whatsmars-cloud-zuul</artifactId>
<name>${project.artifactId}</name>
<properties>
<start-class>org.hongxi.whatsmars.cloud.zuul.ZuulApplication</start-class>
</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.slf4j</groupId>
<artifactId>jcl-over-slf4j</artifactId>
</dependency>
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<build>
<finalName>${project.artifactId}</finalName>
<resources>
<resource>
<directory>src/main/resources</directory>
<filtering>true</filtering>
</resource>
</resources>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
<dependencies>
<dependency>
<groupId>org.springframework</groupId>
<artifactId>springloaded</artifactId>
<version>${springloaded.version}</version>
</dependency>
</dependencies>
<!-- POM不是继承spring-boot-starter-parent的话,需要下面的指定 -->
<configuration>
<mainClass>${start-class}</mainClass>
<layout>ZIP</layout>
</configuration>
<executions>
<execution>
<goals>
<goal>repackage</goal>
</goals>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
\ No newline at end of file
package org.hongxi.whatsmars.cloud.zuul;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.zuul.EnableZuulProxy;
/**
* Created by shenhongxi on 2017/12/27.
*/
@SpringBootApplication
@EnableZuulProxy
public class ZuulApplication {
public static void main(String[] args) {
SpringApplication.run(ZuulApplication.class, args);
}
}
package org.hongxi.whatsmars.cloud.zuul.filter;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.netflix.zuul.ZuulFilter;
import com.netflix.zuul.context.RequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.HttpStatus;
import org.springframework.http.MediaType;
import org.springframework.stereotype.Component;
import javax.servlet.http.HttpServletRequest;
/**
* Created by shenhongxi on 2017/12/27.
*/
@Component
public class AccessFilter extends ZuulFilter {
private final Logger logger = LoggerFactory.getLogger(getClass());
private static final String LOGIN_URL = "http://hongxi.org/login";
@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();
logger.info("{} request to {}", request.getMethod(), request.getRequestURL().toString());
Object accessToken = request.getParameter("accessToken");
if (accessToken == null) {
try {
logger.info("access token is empty");
ReturnMessage message = new ReturnMessage(360, LOGIN_URL, "未登录");
ctx.setSendZuulResponse(false);
ctx.getResponse().setContentType(MediaType.APPLICATION_JSON_UTF8_VALUE);
ctx.setResponseStatusCode(HttpStatus.OK.value());
ctx.setResponseBody(new ObjectMapper().writeValueAsString(message));
} catch (Exception e) {
logger.error("build response fail", e);
}
}
return null;
}
}
package org.hongxi.whatsmars.cloud.zuul.filter;
public class ReturnMessage {
private int status;
private String returnUrl;
private String message;
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getReturnUrl() {
return returnUrl;
}
public void setReturnUrl(String returnUrl) {
this.returnUrl = returnUrl;
}
public String getMessage() {
return message;
}
public void setMessage(String message) {
this.message = message;
}
public ReturnMessage(int status, String returnUrl, String message) {
super();
this.status = status;
this.returnUrl = returnUrl;
this.message = message;
}
public ReturnMessage(int status, String message) {
super();
this.status = status;
this.returnUrl = null;
this.message = message;
}
public ReturnMessage() {
super();
}
}
spring:
profiles:
active: dev
---
eureka:
client:
serviceUrl:
defaultZone: http://test.toutiao.im:8761/eureka/
server:
port: 8764
spring:
application:
name: demo-zuul
profiles: test
---
eureka:
client:
serviceUrl:
defaultZone: http://localhost:8761/eureka/
server:
port: 8764
spring:
application:
name: demo-zuul
profiles: dev
zuul:
routes:
demo:
path: /demo/**
serviceId: demo-consumer
stripPrefix: true
sensitiveHeaders: // 表示不过滤Headers,如Cookie
demo2:
path: /demo2/**
serviceId: demo2-consumer
stripPrefix: true
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<property name="log.context.name" value="whatsmars-cloud-zuul" />
<property name="log.charset" value="UTF-8" />
<property name="log.pattern" value="[%-5level] %date --%thread-- [%logger] %msg %n" />
<contextName>${log.context.name}</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder charset="${log.charset}">
<pattern>${log.pattern}</pattern>
</encoder>
</appender>
<root>
<level value="INFO" />
<appender-ref ref="STDOUT" />
</root>
</configuration>
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册