熬夜肝了這篇Spring Cloud Gateway的功能及綜合使用

前言

SpringCloud 是微服務(wù)中的翹楚喂走,最佳的落地方案。

Spring Cloud Gateway 是 Spring Cloud 新推出的網(wǎng)關(guān)框架奇适,之前是 Netflix Zuul渔嚷。網(wǎng)關(guān)通常在項(xiàng)目中為了簡(jiǎn)化

前端的調(diào)用邏輯,同時(shí)也簡(jiǎn)化內(nèi)部服務(wù)之間互相調(diào)用的復(fù)雜度绽快;具體作用就是轉(zhuǎn)發(fā)服務(wù)芥丧,接收并轉(zhuǎn)發(fā)所有內(nèi)外

部的客戶端調(diào)用;其他常見(jiàn)的功能還有權(quán)限認(rèn)證坊罢,限流控制等等娄柳。

本博客會(huì)提到網(wǎng)關(guān)的基本轉(zhuǎn)發(fā)功能熔斷功能艘绍,限流功能以及功能的綜合使用赤拒。

2021年Java真題面試文檔分享給大家,下面是一張springcloud的技術(shù)點(diǎn)整理:


image

源碼

GitHub地址:https://github.com/intomylife/SpringCloud

環(huán)境

JDK 1.8.0 +

Maven 3.0 +

SpringBoot 2.0.3

SpringCloud Finchley.RELEASE

Redis 3.0 +

開(kāi)發(fā)工具

IntelliJ IDEA

正文

commons 工程

commons 工程 - POM 文件

<?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>
 
    <!-- 三坐標(biāo) -->
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-gateway-commons</artifactId>
    <version>1.0</version>
 
    <!-- 工程名稱和描述 -->
    <name>springcloud-gateway-commons</name>
    <description>公用工程</description>
 
    <!-- 打包方式 -->
    <packaging>jar</packaging>
 
    <!-- 在 properties 下聲明相應(yīng)的版本信息诱鞠,然后在 dependency 下引用的時(shí)候用 ${} 就可以引入該版本 jar 包了 -->
    <properties>
        <!-- 編碼 -->
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <!-- jdk -->
        <java.version>1.8</java.version>
 
        <!-- SpringBoot -->
        <platform-bom.version>Cairo-SR3</platform-bom.version>
 
        <!-- SpringCloud -->
        <spring-cloud-dependencies.version>Finchley.RELEASE</spring-cloud-dependencies.version>
    </properties>
 
    <!-- 加入依賴 -->
    <dependencies>
 
    </dependencies>
 
    <!-- 依賴 jar 包版本管理的管理器 -->
    <!-- 如果 dependencies 里的 dependency 自己沒(méi)有聲明 version 元素挎挖,那么 maven 就此處來(lái)找版本聲明。 -->
    <!-- 如果有航夺,就會(huì)繼承它蕉朵;如果沒(méi)有就會(huì)報(bào)錯(cuò),告訴你沒(méi)有版本信息 -->
    <!-- 優(yōu)先級(jí):如果 dependencies 里的 dependency 已經(jīng)聲明了版本信息阳掐,就不會(huì)生效此處的版本信息了 -->
    <dependencyManagement>
        <dependencies>
            <!-- SpringBoot -->
            <dependency>
                <groupId>io.spring.platform</groupId>
                <artifactId>platform-bom</artifactId>
                <version>${platform-bom.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
            <!-- SpringCloud -->
            <dependency>
                <groupId>org.springframework.cloud</groupId>
                <artifactId>spring-cloud-dependencies</artifactId>
                <version>${spring-cloud-dependencies.version}</version>
                <type>pom</type>
                <scope>import</scope>
            </dependency>
        </dependencies>
    </dependencyManagement>
 
    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

配置一些共用依賴

commons 工程 - 項(xiàng)目結(jié)構(gòu)

image

service 工程

**① 此工程下有四個(gè)模塊:一個(gè)注冊(cè)中心始衅,一個(gè)網(wǎng)關(guān)以及兩個(gè)提供者

② 兩個(gè)提供者除端口不一致以外,其他代碼基本一致

registry-service(注冊(cè)中心)

registry-service - POM 文件

<?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>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-service</artifactId>
        <version>1.0</version>
    </parent>
 
    <!-- 三坐標(biāo) -->
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-gateway-registry-service</artifactId>
    <version>1.0</version>
 
    <!-- 工程名稱描述 -->
    <name>springcloud-gateway-registry-service</name>
    <description>注冊(cè)中心</description>
 
    <!-- 打包方式 -->
    <packaging>jar</packaging>
 
    <!-- 在 properties下聲明相應(yīng)的版本信息缭保,然后在dependency下引用的時(shí)候用 ${} 就可以引入該版本jar包了 -->
    <properties>
 
    </properties>
 
    <!-- 加入依賴 -->
    <dependencies>
        <!-- 服務(wù)注冊(cè)中心 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
        </dependency>
    </dependencies>
 
    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

主要加入 spring-cloud-starter-netflix-eureka-server 依賴

registry-service - application.yml 配置文件

#端口
server:
  port: 8761
 
#應(yīng)用名稱
spring:
  application:
    name: eureka-server
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    # 是否向注冊(cè)中心注冊(cè)自己
    registerWithEureka: false
    # 是否向注冊(cè)中心獲取注冊(cè)信息
    fetchRegistry: false
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/

這里使用了默認(rèn)的 8761 端口汛闸,當(dāng)然也可以更改,不過(guò)在發(fā)現(xiàn)調(diào)用服務(wù)端的注冊(cè)中心地址端口要與它一致

registry-service - 啟動(dòng)類

package com.zwc;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.server.EnableEurekaServer;
 
@SpringBootApplication
@EnableEurekaServer
public class SpringcloudGatewayRegistryServiceApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringcloudGatewayRegistryServiceApplication.class, args);
    }
 
}

在啟動(dòng)類中添加 @EnableEurekaServer 注解表示此工程是注冊(cè)中心

registry-service - 啟動(dòng)項(xiàng)目

  1. 項(xiàng)目啟動(dòng)成功后訪問(wèn) http://localhost:8761/ 即可看到 eureka-server 主頁(yè)面
    image

注:由于服務(wù)工程 A 和服務(wù)工程 B 除端口不一致以外艺骂,其他代碼基本一致诸老,所以服務(wù)工程 B 不再贅述

a-service(服務(wù)工程 A)

a-service - POM 文件

<?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>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-a-service</artifactId>
        <version>1.0</version>
    </parent>
 
    <!-- 三坐標(biāo) -->
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-gateway-a-service-core</artifactId>
    <version>1.0</version>
 
    <!-- 工程名稱描述 -->
    <name>springcloud-gateway-a-service-core</name>
    <description>服務(wù)工程 - A 核心</description>
 
    <!-- 打包方式 -->
    <packaging>jar</packaging>
 
    <!-- 在 properties下聲明相應(yīng)的版本信息,然后在dependency下引用的時(shí)候用 ${} 就可以引入該版本jar包了 -->
    <properties>
 
    </properties>
 
    <!-- 加入依賴 -->
    <dependencies>
        <!-- commons工程 依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>springcloud-gateway-commons</artifactId>
            <version>1.0</version>
        </dependency>
 
        <!-- api工程 依賴 -->
        <dependency>
            <groupId>com.zwc</groupId>
            <artifactId>springcloud-gateway-a-service-api</artifactId>
            <version>1.0</version>
        </dependency>
 
        <!-- springboot web 依賴 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
 
        <!-- 提供者消費(fèi)者 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
    </dependencies>
 
    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

加入spring-cloud-starter-netflix-eureka-client依賴

a-service - application.yml 配置文件

#端口
server:
  port: 9000
 
#應(yīng)用名稱
spring:
  application:
    name: gateway-service
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/

注意此處配置注冊(cè)中心地址的端口為 8761 也就是上面注冊(cè)中心工程配置的端口

a-service - controller 前端控制器(提供服務(wù))

package com.zwc.a.controller;
 
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
/*
 * @ClassName ASayHelloController
 * @Desc TODO   Say Hello
 * @Date 2019/5/20 23:24
 * @Version 1.0
 */
@RestController
public class ASayHelloController {
 
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   讀取配置文件中的端口
     * @Date 2019/5/20 23:24
     * @Version 1.0
     */
    @Value("${server.port}")
    private String port;
 
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   Say Hello
     * @Date 2019/5/20 23:24
     * @Version 1.0
     */
    @RequestMapping("/hello")
    public String hello(){
        return "Hello钳恕!I'm a. port:" + port;
    }
 
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   接收從網(wǎng)關(guān)傳入的參數(shù)
     * @Date 2019/6/23 16:28
     * @Version 1.0
     */
    @RequestMapping("/name")
    public String name(String name){
        return "My name is " + name + ". aaa";
    }
 
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   接收從網(wǎng)關(guān)傳入的參數(shù)
     * @Date 2019/6/23 16:52
     * @Version 1.0
     */
    @RequestMapping("/age")
    public String age(String age){
        return "I am " + age + " years old this year. aaa";
    }
 
    /*
     * @ClassName ASayHelloController
     * @Desc TODO   接收從網(wǎng)關(guān)傳入的參數(shù)
     * @Date 2019/6/29 22:00
     * @Version 1.0
     */
    @RequestMapping("/routeAll")
    public String routeAll(String pass) {
        return "Can I pass? " + pass + "! port:" + port;
    }
 
}

提供輸出字符串服務(wù)别伏,供網(wǎng)關(guān)調(diào)用

a-service - 啟動(dòng)類

package com.zwc;
 
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
 
@SpringBootApplication
@EnableEurekaClient
public class SpringcloudGatewayAServiceCoreApplication {
 
    public static void main(String[] args) {
        SpringApplication.run(SpringcloudGatewayAServiceCoreApplication.class, args);
    }
 
}

添加 @EnableEurekaClient 注解表示此工程可以向注冊(cè)中心提供服務(wù)

a-service - 啟動(dòng)項(xiàng)目

  1. 刷新 http://localhost:8761/(注冊(cè)中心)可以看到服務(wù)已經(jīng)被注冊(cè)進(jìn)來(lái)了
image
  1. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:9000/hello

  2. 輸出內(nèi)容:'Hello!I'm a. port:9000'

  3. 同樣啟動(dòng)服務(wù)工程 B后忧额,刷新 http://localhost:8761/(注冊(cè)中心)

image
  1. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:9001/hello

  2. 輸出內(nèi)容:'Hello厘肮!I'm b. port:9001'

  3. 其他接口是下面網(wǎng)關(guān)服務(wù)啟動(dòng)后轉(zhuǎn)發(fā)調(diào)用的,也是本博客的重頭戲

master-service(網(wǎng)關(guān))

master-service - POM 文件

<?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>
        <groupId>com.zwc</groupId>
        <artifactId>springcloud-gateway-service</artifactId>
        <version>1.0</version>
    </parent>
 
    <!-- 三坐標(biāo) -->
    <groupId>com.zwc</groupId>
    <artifactId>springcloud-gateway-master-service</artifactId>
    <version>1.0</version>
 
    <!-- 工程名稱描述 -->
    <name>springcloud-gateway-master-service</name>
    <description>Spring Cloud Gateway 服務(wù)網(wǎng)關(guān)</description>
 
    <!-- 打包方式 -->
    <packaging>jar</packaging>
 
    <!-- 在 properties下聲明相應(yīng)的版本信息睦番,然后在 dependency 下引用的時(shí)候用 ${} 就可以引入該版本 jar 包了 -->
    <properties>
        <!-- ali json -->
        <fastjson.version>1.2.47</fastjson.version>
    </properties>
 
    <!-- 加入依賴 -->
    <dependencies>
        <!-- 提供者消費(fèi)者 -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
 
        <!-- gateway -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-gateway</artifactId>
        </dependency>
 
        <!-- redis -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-redis-reactive</artifactId>
        </dependency>
 
        <!-- hystrix -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-hystrix</artifactId>
        </dependency>
 
        <!-- ali json依賴 -->
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>fastjson</artifactId>
            <version>${fastjson.version}</version>
        </dependency>
    </dependencies>
 
    <!-- 插件依賴 -->
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
 
</project>

加入spring-cloud-starter-netflix-eureka-client 依賴:提供和注冊(cè)服務(wù)

加入spring-cloud-starter-gateway 依賴:gateway

加入spring-boot-starter-data-redis-reactive 依賴:結(jié)合 Redis 限流

加入spring-cloud-starter-netflix-hystrix 依賴:熔斷器

master-service - application.yml 配置文件

#端口
server:
  port: 8000
 
spring:
  profiles:
    # 指定配置
    # route_simple:簡(jiǎn)單嘗試
    # route_stripPrefix:截取請(qǐng)求
    # route_uri:轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)
    # route_addRequestParameter:轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)
    # route_hystrix:熔斷
    # route_requestRateLimiter:限流
    # route_all:綜合
    active: route_simple
 
---
 
spring:
  # 配置文件名稱类茂,用來(lái)標(biāo)識(shí)不同環(huán)境的配置。由 spring.profiles.active 的值來(lái)決定使用哪組配置抡砂。
  ## 簡(jiǎn)單嘗試
  profiles: route_simple
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合大咱,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由,它由唯一標(biāo)識(shí)(ID)注益、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)溯捆。filters 不是必需參數(shù)丑搔。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)厦瓢,具有唯一性)   簡(jiǎn)單嘗試
      - id: route_simple
        # 目標(biāo)服務(wù)地址(uri:地址,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: https://www.zouwencong.com
        # 路由條件(predicates:斷言啤月,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/archive
        - Path=/archive
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱煮仇,用來(lái)標(biāo)識(shí)不同環(huán)境的配置。由 spring.profiles.active 的值來(lái)決定使用哪組配置谎仲。
  ## 截取請(qǐng)求
  profiles: route_stripPrefix
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合浙垫,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由,它由唯一標(biāo)識(shí)(ID)郑诺、目標(biāo)服務(wù)地址(uri)夹姥、一組斷言(predicates)和一組過(guò)濾器組成(filters)。filters 不是必需參數(shù)辙诞。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)辙售,具有唯一性)   截取請(qǐng)求
      - id: route_simple
        # 目標(biāo)服務(wù)地址(uri:地址,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: https://www.zouwencong.com
        # 路由條件(predicates:斷言飞涂,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/archive旦部,/str 部分會(huì)被下面的過(guò)濾器給截取掉
        - Path=/str/archive
        filters:
        ## 截取路徑位數(shù)
        - StripPrefix=1
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置较店。由 spring.profiles.active 的值來(lái)決定使用哪組配置士八。
  ## 轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)
  profiles: route_uri
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由梁呈,它由唯一標(biāo)識(shí)(ID)曹铃、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)捧杉。filters 不是必需參數(shù)陕见。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)
      - id: route_uri
        # 目標(biāo)服務(wù)地址(uri:地址味抖,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: http://localhost:9000
        # 路由條件(predicates:斷言评甜,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=name, zwc
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱仔涩,用來(lái)標(biāo)識(shí)不同環(huán)境的配置忍坷。由 spring.profiles.active 的值來(lái)決定使用哪組配置。
  ## 轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)
  profiles: route_addRequestParameter
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合熔脂,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由佩研,它由唯一標(biāo)識(shí)(ID)、目標(biāo)服務(wù)地址(uri)霞揉、一組斷言(predicates)和一組過(guò)濾器組成(filters)旬薯。filters 不是必需參數(shù)。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)适秩,具有唯一性)   轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)
      - id: route_addRequestParameter
        # 目標(biāo)服務(wù)地址(uri:地址绊序,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言硕舆,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱骤公,用來(lái)標(biāo)識(shí)不同環(huán)境的配置抚官。由 spring.profiles.active 的值來(lái)決定使用哪組配置。
  ## 熔斷
  profiles: route_hystrix
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合阶捆,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由凌节,它由唯一標(biāo)識(shí)(ID)、目標(biāo)服務(wù)地址(uri)洒试、一組斷言(predicates)和一組過(guò)濾器組成(filters)倍奢。filters 不是必需參數(shù)。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)儡司,具有唯一性)   熔斷
      - id: route_hystrix
        # 目標(biāo)服務(wù)地址(uri:地址娱挨,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器捕犬,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
        ## 熔斷
        - name: Hystrix
          args:
            name: fallbackcmd
            ### fallback 時(shí)調(diào)用的方法 http://localhost:8000/fallback
            fallbackUri: forward:/fallback
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱跷坝,用來(lái)標(biāo)識(shí)不同環(huán)境的配置。由 spring.profiles.active 的值來(lái)決定使用哪組配置碉碉。
  ## 限流
  profiles: route_requestRateLimiter
  redis:
    host: localhost
    port: 6379
    database: 0
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合柴钻,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由,它由唯一標(biāo)識(shí)(ID)垢粮、目標(biāo)服務(wù)地址(uri)贴届、一組斷言(predicates)和一組過(guò)濾器組成(filters)。filters 不是必需參數(shù)蜡吧。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)毫蚓,具有唯一性)   限流
      - id: route_requestRateLimiter
        # 目標(biāo)服務(wù)地址(uri:地址,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言昔善,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器元潘,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
        ## 限流
        - name: RequestRateLimiter
          args:
            ### 限流過(guò)濾器的 Bean 名稱
            key-resolver: '#{@uriKeyResolver}'
            ### 希望允許用戶每秒處理多少個(gè)請(qǐng)求
            redis-rate-limiter.replenishRate: 1
            ### 用戶允許在一秒鐘內(nèi)完成的最大請(qǐng)求數(shù)
            redis-rate-limiter.burstCapacity: 3
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
 
---
 
spring:
  # 配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置君仆。由 spring.profiles.active 的值來(lái)決定使用哪組配置翩概。
  ## 綜合
  profiles: route_all
  redis:
    host: localhost
    port: 6379
    database: 0
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由返咱,它由唯一標(biāo)識(shí)(ID)钥庇、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)咖摹。filters 不是必需參數(shù)评姨。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   綜合
      - id: route_all
        # 目標(biāo)服務(wù)地址(uri:地址楞艾,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言参咙,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/routeAll龄广,/all 部分會(huì)被下面的過(guò)濾器給截取掉
        - Path=/all/routeAll
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器硫眯,過(guò)濾規(guī)則)
        filters:
        ## 截取路徑位數(shù)
        - StripPrefix=1
        ## 添加指定參數(shù)
        - AddRequestParameter=pass, yes
        ## 熔斷
        - name: Hystrix
          args:
            name: fallbackcmd
            ### fallback 時(shí)調(diào)用的方法 http://localhost:8000/fallback
            fallbackUri: forward:/fallback
        ## 限流
        - name: RequestRateLimiter
          args:
            ### 限流過(guò)濾器的 Bean 名稱
            key-resolver: '#{@uriKeyResolver}'
            ### 希望允許用戶每秒處理多少個(gè)請(qǐng)求
            redis-rate-limiter.replenishRate: 1
            ### 用戶允許在一秒鐘內(nèi)完成的最大請(qǐng)求數(shù)
            redis-rate-limiter.burstCapacity: 3
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug

注意配置注冊(cè)中心地址的端口都為 8761 也就是上面注冊(cè)中心工程配置的端口

每一對(duì) '---' 符號(hào)中的配置文件都是單獨(dú)的蕴侧,使用 spring.profiles.active 指定

每一對(duì) '---' 符號(hào)中的配置文件都只配置了一個(gè) route(路由)

route(路由)由四部分組成,其中 filters 不是必須參數(shù)

唯一標(biāo)識(shí)(ID)两入、目標(biāo)服務(wù)地址(uri)净宵、一組斷言(predicates)和一組過(guò)濾器組成(filters)

master-service - 簡(jiǎn)單嘗試

spring:
  # 配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置裹纳。由 spring.profiles.active 的值來(lái)決定使用哪組配置择葡。
  ## 簡(jiǎn)單嘗試
  profiles: route_simple
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由剃氧,它由唯一標(biāo)識(shí)(ID)敏储、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)朋鞍。filters 不是必需參數(shù)已添。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   簡(jiǎn)單嘗試
      - id: route_simple
        # 目標(biāo)服務(wù)地址(uri:地址滥酥,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: https://www.zouwencong.com
        # 路由條件(predicates:斷言更舞,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/archive
        - Path=/archive
  1. 停止注冊(cè)中心工程(registry-service)、服務(wù)工程 A 和服務(wù)工程 B

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_simple

  3. 上面配置文件內(nèi)容意思是當(dāng)訪問(wèn) http://localhost:8000/archive (網(wǎng)關(guān)地址/archive)

    會(huì)被轉(zhuǎn)發(fā)到 https://www.zouwencong.com/archive/ (uri/archive)

  4. 啟動(dòng)注冊(cè)中心工程(registry-service)和網(wǎng)關(guān)工程(master-service)

  5. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/archive

  6. 發(fā)現(xiàn)頁(yè)面會(huì)自動(dòng)被跳轉(zhuǎn)到:https://www.zouwencong.com/archive/

  7. 證明服務(wù)轉(zhuǎn)發(fā)成功

master-service - 截取請(qǐng)求

spring:
  #配置文件名稱坎吻,用來(lái)標(biāo)識(shí)不同環(huán)境的配置缆蝉。由 spring.profiles.active 的值來(lái)決定使用哪組配置。
  ##截取請(qǐng)求
  profiles: route_stripPrefix
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合瘦真,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由刊头,它由唯一標(biāo)識(shí)(ID)、目標(biāo)服務(wù)地址(uri)诸尽、一組斷言(predicates)和一組過(guò)濾器組成(filters)原杂。filters 不是必需參數(shù)。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)弦讽,具有唯一性)   截取請(qǐng)求
      - id: route_simple
        # 目標(biāo)服務(wù)地址(uri:地址污尉,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: https://www.zouwencong.com
        # 路由條件(predicates:斷言,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/archive往产,/str 部分會(huì)被下面的過(guò)濾器給截取掉
        - Path=/str/archive
        filters:
        ## 截取路徑位數(shù)
        - StripPrefix=1
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)和網(wǎng)關(guān)工程(master-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_stripPrefix

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/str/archive (網(wǎng)關(guān)地址/str/archive)截取 /str 部分被碗,

    截取后被轉(zhuǎn)發(fā)到 https://www.zouwencong.com/archive/ (uri/archive)

  4. 啟動(dòng)注冊(cè)中心工程(registry-service)和網(wǎng)關(guān)工程(master-service)

  5. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/str/archive

  6. 發(fā)現(xiàn)頁(yè)面會(huì)自動(dòng)被跳轉(zhuǎn)到:https://www.zouwencong.com/archive/

  7. 證明路徑被截取并服務(wù)轉(zhuǎn)發(fā)成功

master-service - 轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)

spring:
  #配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置仿村。由 spring.profiles.active 的值來(lái)決定使用哪組配置锐朴。
  ##轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)
  profiles: route_uri
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由蔼囊,它由唯一標(biāo)識(shí)(ID)焚志、目標(biāo)服務(wù)地址(uri)衣迷、一組斷言(predicates)和一組過(guò)濾器組成(filters)。filters 不是必需參數(shù)酱酬。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)壶谒,具有唯一性)   轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)
      - id: route_uri
        # 目標(biāo)服務(wù)地址(uri:地址,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: http://localhost:9000
        # 路由條件(predicates:斷言膳沽,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器汗菜,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=name, zwc
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)和網(wǎng)關(guān)工程(master-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_uri

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/name (網(wǎng)關(guān)地址/name)

    會(huì)被轉(zhuǎn)發(fā)到 http://localhost:9000/name(uri/name),并傳入 'name=zwc' 參數(shù)(注意為 Get 請(qǐng)求)

  4. 啟動(dòng)注冊(cè)中心工程(registry-service),網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A(a-service)

  5. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/name

  6. 輸出內(nèi)容:'My name is zwc. aaa'(通過(guò)網(wǎng)關(guān)轉(zhuǎn)發(fā) - 參數(shù)有值)

  7. 打開(kāi)新頁(yè)面訪問(wèn):http://localhost:9000/name

  8. 輸出內(nèi)容:'My name is null. aaa'(直接訪問(wèn) - 參數(shù)沒(méi)有值)

  9. 證明轉(zhuǎn)發(fā)指定地址并傳入?yún)?shù)成功

master-service - 轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)

spring:
  #配置文件名稱挑社,用來(lái)標(biāo)識(shí)不同環(huán)境的配置陨界。由 spring.profiles.active 的值來(lái)決定使用哪組配置。
  ##轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)
  profiles: route_addRequestParameter
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合痛阻,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由菌瘪,它由唯一標(biāo)識(shí)(ID)、目標(biāo)服務(wù)地址(uri)阱当、一組斷言(predicates)和一組過(guò)濾器組成(filters)俏扩。filters 不是必需參數(shù)。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí)斗这,具有唯一性)   轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)
      - id: route_addRequestParameter
        # 目標(biāo)服務(wù)地址(uri:地址动猬,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器表箭,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)赁咙,網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A(a-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_addRequestParameter

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/age (網(wǎng)關(guān)地址/age)會(huì)被轉(zhuǎn)發(fā)到 http://gateway-service/age(uri/age),并傳入 'age=three' 參數(shù)(注意為 Get 請(qǐng)求)

  4. 注意此處的配置 uri: lb://gateway-service 與之前都有所不同免钻,之前都是指定了明確的轉(zhuǎn)發(fā)地址彼水,可以滿足單個(gè)服務(wù)轉(zhuǎn)發(fā)的需求,但是一般情況都會(huì)有多個(gè)服務(wù)极舔,所以這里是指定的服務(wù)名稱凤覆,格式為:lb://應(yīng)用注冊(cè)服務(wù)名。

  5. 啟動(dòng)注冊(cè)中心工程(registry-service),網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service拆魏、b-service)

  6. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/age

  7. 這時(shí)可能會(huì)報(bào)錯(cuò) 500.錯(cuò)誤信息為 'Unable to find instance for gateway-service'

  8. 這種情況不要慌張盯桦,只是服務(wù)還沒(méi)有被注冊(cè)到注冊(cè)中心,稍等片刻再訪問(wèn)

  9. 多次訪問(wèn):http://localhost:8000/age

  10. 輪流輸出內(nèi)容:'I am three years old this year. aaa' 和 'I am three years old this year. bbb'

  11. 此時(shí)還通過(guò)網(wǎng)關(guān)達(dá)到了負(fù)載均衡的效果

  12. 證明轉(zhuǎn)發(fā)指定服務(wù)并傳入?yún)?shù)成功

master-service - 熔斷

spring:
  #配置文件名稱渤刃,用來(lái)標(biāo)識(shí)不同環(huán)境的配置拥峦。由 spring.profiles.active 的值來(lái)決定使用哪組配置。
  ##熔斷
  profiles: route_hystrix
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合卖子,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由略号,它由唯一標(biāo)識(shí)(ID)、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)玄柠。filters 不是必需參數(shù)突梦。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   熔斷
      - id: route_hystrix
        # 目標(biāo)服務(wù)地址(uri:地址羽利,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言宫患,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
        ## 熔斷
        - name: Hystrix
          args:
            name: fallbackcmd
            ### fallback 時(shí)調(diào)用的方法 http://localhost:8000/fallback
            fallbackUri: forward:/fallback
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)铐伴,網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service撮奏、b-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_hystrix

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/age (網(wǎng)關(guān)地址/age)會(huì)被轉(zhuǎn)發(fā)到 http://gateway-service/age(uri/age)俏讹,并傳入 'age=three' 參數(shù)(注意為 Get 請(qǐng)求)

  4. 注意此處的配置 uri: lb://gateway-service 與之前都有所不同当宴,之前都是指定了明確的轉(zhuǎn)發(fā)地址,可以滿足單個(gè)服務(wù)轉(zhuǎn)發(fā)的需求泽疆,但是一般情況都會(huì)有多個(gè)服務(wù)户矢,所以這里是指定的服務(wù)名稱,格式為:lb://應(yīng)用注冊(cè)服務(wù)名殉疼。

  5. 此處還多配置了一個(gè)過(guò)濾器 '- name: Hystrix'(熔斷)

  6. 當(dāng)請(qǐng)求服務(wù)出錯(cuò)時(shí)梯浪,會(huì)調(diào)用 fallback,路徑為:http://localhost:8000/fallback (網(wǎng)關(guān)地址/fallback)

  7. 此時(shí)就需要如下前端控制器

master-service - 熔斷 - controller

package com.zwc.gateway.hystrix;
 
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
 
/**
 * @ClassName FallbackController
 * @Desc TODO   網(wǎng)關(guān)斷路器
 * @Date 2019/6/23 19:33
 * @Version 1.0
 */
@RestController
public class FallbackController {
 
    /*
     * @ClassName FallbackController
     * @Desc TODO   網(wǎng)關(guān)斷路器
     * @Date 2019/6/23 19:35
     * @Version 1.0
     */
    @RequestMapping("/fallback")
    public String fallback() {
        return "I'm Spring Cloud Gateway fallback.";
    }
 

}

  1. 啟動(dòng)注冊(cè)中心工程(registry-service),網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service瓢娜、b-service)

  2. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/age

  3. 輸出內(nèi)容:'I'm Spring Cloud Gateway fallback.'

  4. 證明熔斷成功

master-service - 限流(重點(diǎn)挂洛,解決不生效問(wèn)題)

spring:
  #配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置眠砾。由 spring.profiles.active 的值來(lái)決定使用哪組配置虏劲。
  ##限流
  profiles: route_requestRateLimiter
  redis:
    host: localhost
    port: 6379
    database: 0
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由褒颈,它由唯一標(biāo)識(shí)(ID)柒巫、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)谷丸。filters 不是必需參數(shù)堡掏。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   限流
      - id: route_requestRateLimiter
        # 目標(biāo)服務(wù)地址(uri:地址刨疼,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言泉唁,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器,過(guò)濾規(guī)則)
        filters:
        ## 添加指定參數(shù)
        - AddRequestParameter=age, three
        ## 限流
        - name: RequestRateLimiter
          args:
            ### 限流過(guò)濾器的 Bean 名稱
            key-resolver: '#{@uriKeyResolver}'
            ### 希望允許用戶每秒處理多少個(gè)請(qǐng)求
            redis-rate-limiter.replenishRate: 1
            ### 用戶允許在一秒鐘內(nèi)完成的最大請(qǐng)求數(shù)
            redis-rate-limiter.burstCapacity: 3
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)揩慕,網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service亭畜、b-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改route_requestRateLimiter

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/age (網(wǎng)關(guān)地址/age)會(huì)被轉(zhuǎn)發(fā)到 http://gateway-service/age(uri/age),并傳入 'age=three' 參數(shù)(注意為 Get 請(qǐng)求)

  4. 注意此處還需要配置 redis 的連接信息

  5. 注意此處是結(jié)合 redis 實(shí)現(xiàn)的限流漩绵,所以 filter 過(guò)濾器的 name 必須為 RequestRateLimiter

  6. 并且通過(guò)實(shí)現(xiàn) KeyResolver 類來(lái)自定義限流策略贱案,如下

master-service - 限流 - 策略

package com.zwc.gateway.config.filters;
 
import org.springframework.cloud.gateway.filter.ratelimit.KeyResolver;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
 
/**
 * @ClassName UriKeyResolver
 * @Desc TODO   Spring Cloud Gateway 網(wǎng)關(guān)限流過(guò)濾器
 * @Date 2019/6/23 17:59
 * @Version 1.0
 */
public class UriKeyResolver implements KeyResolver {
 
    /*
     * @ClassName UriKeyResolver
     * @Desc TODO   根據(jù)請(qǐng)求的 uri 限流
     * @Date 2019/6/29 17:25
     * @Version 1.0
     */
    @Override
    public Mono<String> resolve(ServerWebExchange exchange) {
        return Mono.just(exchange.getRequest().getURI().getPath());
    }
 
}
  1. 啟動(dòng)本地 redis(redis-server.exe) 服務(wù)

  2. 啟動(dòng)注冊(cè)中心工程(registry-service),網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service、b-service)

  3. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/age

  4. 此時(shí)限流卻無(wú)論如何都不生效,原因有如下兩點(diǎn)

① redis-server 版本過(guò)低宝踪!我 Windows 本地是 redis-2.4.2 版本的侨糟,要用 3 以上的版本!4裨铩秕重!

② 數(shù)據(jù)在 redis 中存儲(chǔ)的時(shí)間只有幾秒,所以得使用 monitor 指令來(lái)動(dòng)態(tài)的觀察@靼颉H茉拧!

  1. 打開(kāi) redis-cli.exe服鹅,輸入命令 monitor

  2. 快速刷新地址:http://localhost:8000/age

  3. 頁(yè)面上會(huì)出現(xiàn) 429凳兵,redis-cli.exe 中會(huì)出現(xiàn)很多數(shù)據(jù)交互(request_rate_limiter.xxx 開(kāi)頭的 key)

  4. 證明限流成功

master-service - 綜合

spring:
  #配置文件名稱,用來(lái)標(biāo)識(shí)不同環(huán)境的配置企软。由 spring.profiles.active 的值來(lái)決定使用哪組配置庐扫。
  ##綜合
  profiles: route_all
  redis:
    host: localhost
    port: 6379
    database: 0
  application:
    # 應(yīng)用名稱
    name: gateway-master
  cloud:
    gateway:
      discovery:
        locator:
          # 是否和服務(wù)注冊(cè)與發(fā)現(xiàn)組件結(jié)合,設(shè)置為 true 后可以直接使用應(yīng)用名稱調(diào)用服務(wù)
          enabled: true
      # 路由(routes:路由仗哨,它由唯一標(biāo)識(shí)(ID)形庭、目標(biāo)服務(wù)地址(uri)、一組斷言(predicates)和一組過(guò)濾器組成(filters)厌漂。filters 不是必需參數(shù)萨醒。)
      routes:
      # 路由標(biāo)識(shí)(id:標(biāo)識(shí),具有唯一性)   綜合
      - id: route_all
        # 目標(biāo)服務(wù)地址(uri:地址苇倡,請(qǐng)求轉(zhuǎn)發(fā)后的地址)
        uri: lb://gateway-service
        # 路由條件(predicates:斷言富纸,匹配 HTTP 請(qǐng)求內(nèi)容)
        predicates:
        ## 轉(zhuǎn)發(fā)地址格式為 uri/routeAll,/all 部分會(huì)被下面的過(guò)濾器給截取掉
        - Path=/all/routeAll
        ## 匹配 GET 請(qǐng)求
        - Method=GET
        # 過(guò)濾器(filters:過(guò)濾器雏节,過(guò)濾規(guī)則)
        filters:
        ## 截取路徑位數(shù)
        - StripPrefix=1
        ## 添加指定參數(shù)
        - AddRequestParameter=pass, yes
        ## 熔斷
        - name: Hystrix
          args:
            name: fallbackcmd
            ### fallback 時(shí)調(diào)用的方法 http://localhost:8000/fallback
            fallbackUri: forward:/fallback
        ## 限流
        - name: RequestRateLimiter
          args:
            ### 限流過(guò)濾器的 Bean 名稱
            key-resolver: '#{@uriKeyResolver}'
            ### 希望允許用戶每秒處理多少個(gè)請(qǐng)求
            redis-rate-limiter.replenishRate: 1
            ### 用戶允許在一秒鐘內(nèi)完成的最大請(qǐng)求數(shù)
            redis-rate-limiter.burstCapacity: 3
 
eureka:
  instance:
    # 使用 ip 代替實(shí)例名
    prefer-ip-address: true
    # 實(shí)例的主機(jī)名
    hostname: ${spring.cloud.client.ip-address}
    # 實(shí)例的 ID 規(guī)則
    instance-id: ${spring.cloud.client.ip-address}:${spring.application.name}:${server.port}
  client:
    serviceUrl:
      # 注冊(cè)中心地址
      defaultZone: http://${eureka.instance.hostname}:8761/eureka/
 
logging:
  level:
    # log 級(jí)別
    org.springframework.cloud.gateway: debug
  1. 停止注冊(cè)中心工程(registry-service)胜嗓,網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service、b-service)

  2. 把 master-service - application.yml 配置文件中最上面的 spring.profiles.active 的值更改為 route_all

  3. 上面配置文件內(nèi)容意思是訪問(wèn)的路徑 http://localhost:8000/all/routeAll (網(wǎng)關(guān)地址/all/routeAll)截取 /all 部分钩乍,會(huì)被轉(zhuǎn)發(fā)到 http://gateway-service/routeAll(uri/routeAll)辞州,并傳入 'pass=yes' 參數(shù)(注意為 Get 請(qǐng)求)

  4. 啟動(dòng)注冊(cè)中心工程(registry-service),網(wǎng)關(guān)工程(master-service)和服務(wù)工程 A/B(a-service、b-service)

  5. 項(xiàng)目啟動(dòng)成功后訪問(wèn):http://localhost:8000/all/routeAll

  6. 首先會(huì)返回 'I'm Spring Cloud Gateway fallback.'寥粹,因?yàn)榉?wù)還未被注冊(cè)到注冊(cè)中心

  7. 然后會(huì)返回 '{"msg":"缺少憑證","code":-1}'变过,因?yàn)榕渲昧巳诌^(guò)濾器,如下

package com.zwc.gateway.config.filters;
 
import com.alibaba.fastjson.JSONObject;
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.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;
import org.springframework.core.io.buffer.DataBuffer;
 
import java.net.InetSocketAddress;
import java.nio.charset.StandardCharsets;
 
/**
 * @ClassName TokenFilter
 * @Desc TODO   請(qǐng)求認(rèn)證過(guò)濾器
 * @Date 2019/6/29 17:49
 * @Version 1.0
 */
public class TokenFilter implements GlobalFilter{
 
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        // 請(qǐng)求對(duì)象
        ServerHttpRequest request = exchange.getRequest();
        // 響應(yīng)對(duì)象
        ServerHttpResponse response = exchange.getResponse();
 
        // 只有綜合路由才添加這個(gè)全局過(guò)濾器(routesId:route_all)
        // 如果請(qǐng)求路徑中不存在 routeAll 字符串
        if(request.getURI().toString().indexOf("routeAll") == -1){
            System.out.println("filter -> return");
            // 直接跳出
            return chain.filter(exchange);
        }
 
        // 從請(qǐng)求中獲取 token 參數(shù)
        String token = exchange.getRequest().getQueryParams().getFirst("token");
        // 如果為空涝涤,那么將返回 401
        if (token == null || token.isEmpty()) {
 
            // 響應(yīng)消息內(nèi)容對(duì)象
            JSONObject message = new JSONObject();
            // 響應(yīng)狀態(tài)
            message.put("code", -1);
            // 響應(yīng)內(nèi)容
            message.put("msg", "缺少憑證");
            // 轉(zhuǎn)換響應(yīng)消息內(nèi)容對(duì)象為字節(jié)
            byte[] bits = message.toJSONString().getBytes(StandardCharsets.UTF_8);
            DataBuffer buffer = response.bufferFactory().wrap(bits);
            // 設(shè)置響應(yīng)對(duì)象狀態(tài)碼 401
            response.setStatusCode(HttpStatus.UNAUTHORIZED);
            // 設(shè)置響應(yīng)對(duì)象內(nèi)容并且指定編碼媚狰,否則在瀏覽器中會(huì)中文亂碼
            response.getHeaders().add("Content-Type", "text/plain;charset=UTF-8");
            // 返回響應(yīng)對(duì)象
            return response.writeWith(Mono.just(buffer));
        }
        // 獲取請(qǐng)求地址
        String beforePath = request.getPath().pathWithinApplication().value();
        // 獲取響應(yīng)狀態(tài)碼
        HttpStatus beforeStatusCode = response.getStatusCode();
        System.out.println("響應(yīng)碼:" + beforeStatusCode + ",請(qǐng)求路徑:" + beforePath);
        // 請(qǐng)求前
        System.out.println("filter -> before");
        // 如果不為空阔拳,就通過(guò)
        return chain.filter(exchange).then(Mono.fromRunnable(() -> {
            // 獲取請(qǐng)求地址
            String afterPath = request.getPath().pathWithinApplication().value();
            // 獲取響應(yīng)狀態(tài)碼
            HttpStatus afterStatusCode = response.getStatusCode();
            System.out.println("響應(yīng)碼:" + afterStatusCode + "崭孤,請(qǐng)求路徑:" + afterPath);
            // 響應(yīng)后
            System.out.println("filter -> after");
        }));
    }
 
}
  1. 全局過(guò)濾器,不需要配置在配置文件中,作用于所有路由辨宠;只是這里在處理前做了判斷遗锣,只有路徑中存在routeAll 字符串才到后續(xù)處理;并且處理分為請(qǐng)求前的處理嗤形,和響應(yīng)后的處理

  2. 此時(shí)在地址:http://localhost:8000/all/routeAll 中添加 token 參數(shù)

  3. 訪問(wèn):http://localhost:8000/all/routeAll?token=123

  4. 輪流輸出內(nèi)容:'Can I pass? yes! port:9000' 和 'Can I pass? yes! port:9001'

  5. 觀察 gateway 工程的控制臺(tái)精偿,會(huì)有如下內(nèi)容輸出

響應(yīng)碼:null,請(qǐng)求路徑:/routeAll
filter -> before
響應(yīng)碼:200赋兵,請(qǐng)求路徑:/routeAll
filter -> after
 13. 證明全局過(guò)濾器過(guò)濾成功

service 工程 - 項(xiàng)目結(jié)構(gòu)

image

把多工程項(xiàng)目使用 IntelliJ IDEA 打開(kāi)

1.把項(xiàng)目從 GitHub 中下載到你的本地

2.打開(kāi) IntelliJ IDEA

3.點(diǎn)擊 File -> Open

4.打開(kāi)你下載到本地的項(xiàng)目目錄

5.springcloud-gateway -> springcloud-gateway-service(選擇打開(kāi)此工程)

6.打開(kāi) service 工程后

7.再次點(diǎn)擊 File -> Project Structrue

8.選擇 Modules笔咽,點(diǎn)擊 '+' 符號(hào)

9.點(diǎn)擊 Import Module

10.還是打開(kāi)你下載到本地的項(xiàng)目目錄

11.springcloud-gateway -> springcloud-gateway-commons -> pom.xml

12.點(diǎn)擊 OK

13.點(diǎn)擊 Next,F(xiàn)inish

14.點(diǎn)擊 Apply霹期,OK

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末叶组,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子经伙,更是在濱河造成了極大的恐慌扶叉,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件帕膜,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡溢十,警方通過(guò)查閱死者的電腦和手機(jī)垮刹,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)张弛,“玉大人荒典,你說(shuō)我怎么就攤上這事⊥萄迹” “怎么了寺董?”我有些...
    開(kāi)封第一講書(shū)人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)刻剥。 經(jīng)常有香客問(wèn)我遮咖,道長(zhǎng),這世上最難降的妖魔是什么造虏? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任御吞,我火速辦了婚禮,結(jié)果婚禮上漓藕,老公的妹妹穿的比我還像新娘陶珠。我一直安慰自己,他們只是感情好享钞,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開(kāi)白布揍诽。 她就那樣靜靜地躺著,像睡著了一般。 火紅的嫁衣襯著肌膚如雪暑脆。 梳的紋絲不亂的頭發(fā)上交排,一...
    開(kāi)封第一講書(shū)人閱讀 52,584評(píng)論 1 312
  • 那天,我揣著相機(jī)與錄音饵筑,去河邊找鬼埃篓。 笑死,一個(gè)胖子當(dāng)著我的面吹牛根资,可吹牛的內(nèi)容都是我干的架专。 我是一名探鬼主播,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼玄帕,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼部脚!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起裤纹,我...
    開(kāi)封第一講書(shū)人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤委刘,失蹤者是張志新(化名)和其女友劉穎,沒(méi)想到半個(gè)月后鹰椒,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體锡移,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年漆际,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了淆珊。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡奸汇,死狀恐怖施符,靈堂內(nèi)的尸體忽然破棺而出女阀,到底是詐尸還是另有隱情值桩,我是刑警寧澤曙寡,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布蚣常,位于F島的核電站改化,受9級(jí)特大地震影響淮野,放射性物質(zhì)發(fā)生泄漏痊远。R本人自食惡果不足惜狭瞎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一柬采、第九天 我趴在偏房一處隱蔽的房頂上張望欢唾。 院中可真熱鬧,春花似錦粉捻、人聲如沸礁遣。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)祟霍。三九已至杏头,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間沸呐,已是汗流浹背醇王。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留崭添,地道東北人寓娩。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像呼渣,于是被迫代替她去往敵國(guó)和親棘伴。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

推薦閱讀更多精彩內(nèi)容