server:
port: 8001 #当前服务端口号
spring:
application:
name: cloud-payment-service #当前服务名称
datasource:
type: com.alibaba.druid.pool.DruidDataSource #当前数据源操作类型
driver-class-name: com.mysql.cj.jdbc.Driver #mysql驱动包
url: jdbc:mysql://localhost:3306/test01?serverTimezone=GMT%2B8 #连接的库
username: root
password:
#=================eureka相关配置======================
eureka:
client:
register-with-eureka: true #true 表示将当前服务注册到eureka注册中心
#true 表示是否在注册中心抓取已有的注册信息,集群环境时必须为true,配合ribbon进行负载
fetchRegistry: true
service-url:
#eureka 注册中心访问连接,集群环境多个注册地址
defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
instance:
instance-id: payment8001 #配置当前服务向eureka注册中心注册时显示的服务器主机名称
prefer-ip-address: true #配置在开发人员直接访问eureka服务器时显示当前eureka上注册的服务的ip
lease-renewal-interval-in-seconds: 1 #指定定时向eureka注册中心发送代表当前服务心跳包的时间默认30秒
lease-expiration-duration-in-seconds: 2 # Eureka 接收到当前服务最后一次发送代表正常心跳包的等待时间,超过则将当前服务在 Eureka 上踢除
#=================eureka相关配置end======================
mybatis:
mapperLocations: classpath:mapper/*.xml #扫描mappper.xml */
type-aliases-package: com.test.dao #扫描对应mapper.xml 接口
@RestController
public class PaymentController {
@Autowired
private PaymentServerApi paymentServerApi;
@GetMapping(value = "/getRun")
public JsonResult getRun() {
System.out.println("执行查询所有数据8001");
return JsonResult.success();
}
@GetMapping(value = "/payment/getById/{id}")
public JsonResult getById(@PathVariable("id") Long id) {
return paymentServerApi.getPaymentById(id);
}
}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient //表示当前 PaymentMain8001 服务注册到Eureka中
public class PaymentMain8001 {
public static void main(String[] args) {
SpringApplication.run(PaymentMain8001.class,args);
}
}
<!--gateway-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
</dependency>
server:
port: 9527
spring:
application:
name: cloud-gateway #当前服务名称
cloud:
gateway:
discovery:
locator:
enabled: true #开启网关通过注册中心动态创建路由功能,利用微服务进行路由
routes:
#分组路由,可以定义多个
- id: payment_route # 路由的id,没有规定规则但要求唯一,建议配合服务名
#uri: http://localhost:8001 #转发到的真实服务器地址(该方式是写死的)
uri: lb://cloud-payment-service #目标服务在注册中心的名称
#配置断言条件(可以简单理解为通过网关转发请求访问上面 uri 配置的服务下的接口,
#执行下面 predicates 中配置的断言,可以同时配置多个,符合条件则放行
predicates:
- Path=/payment/getById/** #Path路径断言,通过网关访问服务时判断访问路径是否是path指定的,"**"表示模糊匹配*/
#分组路由"payment_route2"
- id: payment_route2
#uri: http://localhost:8001
uri: lb://cloud-payment-service
predicates:
- Path=/getRun
#After 断言在指定时间以后才可以通过网关访问uri设置的服务上的接口
#这个时间字符串可以通过 ZonedDateTime获取
- After=2020-05-01T02:46:36.560+08:00[Asia/Shanghai]
#配置过滤器
filters:
#Gateway内置GatewayFilter类型过滤器
#表示会对接收到的请求添加"X-Request-Foo"请求头,并且值为"Bar"
- AddRequestHeader=X-Request-Foo, Bar
#将当前 Gateway 服务注册到 Eureka注册中心
eureka:
client:
register-with-eureka: true #true 表示将当前服务注册到eureka注册中心
#true 表示是否在注册中心抓取已有的注册信息,集群环境时必须为true,配合ribbon进行负载
fetchRegistry: true
service-url:
#eureka 注册中心访问连接,集群环境多个注册地址
defaultZone: http://127.0.0.1:7001/eureka,http://127.0.0.1:7002/eureka
instance:
instance-id: gateway9527 #配置当前服务向eureka注册中心注册时显示的服务器主机名称
prefer-ip-address: true #配置在开发人员直接访问eureka服务器时显示当前eureka上注册的服务的ip
lease-renewal-interval-in-seconds: 1 #指定定时向eureka注册中心发送代表当前服务心跳包的时间默认30秒
# Eureka 接收到当前服务最后一次发送代表正常心跳包的等待时间,超过则将当前服务在 Eureka 上踢除
lease-expiration-duration-in-seconds: 2
hostname: cloud-gateway-service
#=================eureka相关配置end======================
一些其它的 predicates 断言与 filters 示例,如果需求中用到可以配置在yml 中
predicates:
#Before 断言在指定时间以前才可以通过网关访问uri设置的服务上的接口
- Before=2020-05-01T02:46:36.560+08:00[Asia/Shanghai]
#Between 指定时间范围,在该范围内才允许访问
- Between=2020-05-01T02:46:36.560+08:00[Asia/Shanghai],2021-05-01T02:46:36.560+08:00[Asia/Shanghai]
#Cookie 断言,匹配是否携带了key为username,值是否与"aaa"匹配
- Cookie=username,aaa
#Header 请求头断言,匹配请求头中是携带 X-Request-Id 数据,值是否与"\d+"正则匹配
- Header=X-Request-Id,\d+
#Host 断言,匹配访问时的host是否与指定的正则匹配
- Host=**.com
#Method 断言,匹配是否是指定的请求方式
- Method=GET
#Query 断言,匹配发送的请求是否包含名为 "valName" 的参数,并且值要与后面的"\d+"正则匹配
- Query=valName,\d+
#配置过滤器
filters:
#表示对请求添加名为"foo"的参数,值为"bar"
- AddRequestParameter=foo, bar
#表示请求执行完毕后添加名为"X-Response-Foo"响应头,值为"Bar"
- AddResponseHeader=X-Response-Foo, Bar
#保留原始请求的host头信息,而不是通过Gateway网关转发后的请求头
- PreserveHostHeader
#匹配ip
- RemoteAddr=127.0.0.1
#路径重写过滤器,假设上面配置的"predicates:- Path=/server-api/getRun",在请求服务时每次都需要携带"/server-api"路径
#通过此方式,重新路径,假设以前请求服务接口为"当前网关服务ip地址:当前网关服务端口号/server-api/getRun"
#使用路径重写过滤器后可以直接访问"当前网关服务ip地址:当前网关服务端口号/getRun",会自动在端口号后添加 RewritePath 指定的
#"/server-api",其中",/$\{segment} "正则表达式表示空
- RewritePath=/server-api/(?<segment>.*),/$\{
segment}
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
@SpringBootApplication
@EnableEurekaClient
public class GatewayMain9527 {
public static void main(String[] args) {
SpringApplication.run(GatewayMain9527.class,args);
}
}
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpStatus;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.util.MultiValueMap;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class MyGatewayFilter implements GlobalFilter, Ordered {
//1.过滤方法,在方法中当 GatewayFilterChain 调用 filter() 时代表过滤放行,执行下一个过滤
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
System.out.println("自定过滤器执行");
//1.通过 ServerWebExchange 获取 Request,拿到用户发送请求时的所有信息
ServerHttpRequest request = exchange.getRequest();
//获取请求头
request.getHeaders();
//获取uri
request.getURI();
//获取请求体
request.getBody();
//2.此处以获取请求携带的参数
MultiValueMap<String, String> valueMap = request.getQueryParams();
//判断是否存有名字为"name"的参数
String nameVal = valueMap.getFirst("name");
if(null == nameVal){
System.out.println("过滤拦击返回执行");
//3.通过 ServerWebExchange 获取 Response,设置响应前台的数据
ServerHttpResponse response = exchange.getResponse();
//此处以没有"name"值时响应前台不被接受的响应码
response.setStatusCode(HttpStatus.NOT_ACCEPTABLE);
//4.响应前台拒绝访问
return response.setComplete();
}
//5.当 GatewayFilterChain 调用 filter() 方法时代表拦截放行向下执行下一个过滤器
return chain.filter(exchange);
}
//2.优先级,通过该方法返回的int值来设置当前过滤器加载执行的优先级,越小优先级越高
@Override
public int getOrder() {
return 0;
}
}
@RestController
@CrossOrigin //表示该类下的接口支持跨域请求
public class PaymentController {
@Autowired
private PaymentServerApi paymentServerApi;
@GetMapping(value = "/getRun")
public JsonResult getRun() {
System.out.println("执行查询所有数据8001");
return JsonResult.success();
}
}
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.core.Ordered;
import org.springframework.http.HttpHeaders;
import org.springframework.http.server.reactive.ServerHttpRequest;
import org.springframework.http.server.reactive.ServerHttpResponse;
import org.springframework.stereotype.Component;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
@Component
public class CrossGatewayFilter implements GlobalFilter, Ordered {
@Override
public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
ServerHttpRequest request = exchange.getRequest();
ServerHttpResponse response = exchange.getResponse();
HttpHeaders headers = response.getHeaders();
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_METHODS,"POST,GET,PUT,DELETE");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_CREDENTIALS, "true");
headers.add(HttpHeaders.ACCESS_CONTROL_ALLOW_HEADERS, "*");
headers.add(HttpHeaders.ACCESS_CONTROL_EXPOSE_HEADERS,"*");
return chain.filter(exchange);
}
@Override
public int getOrder() {
return 0;
}
}