《五》稽莉、springcloud微服務——Ribbon負載均衡

Spring Cloud Ribbon是基于Netflix Ribbon實現(xiàn)的一套客戶端的 負載均衡的工具瀑志。
Ribbon源碼:https://github.com/Netflix/ribbon

一、Ribbon的配置初步

1污秆、修改 microservicecloud-consumer-dept-80 工程

(1)劈猪、修改pom.xml文件
?? 添加Ribbon 相關依賴

      <!-- Ribbon相關 -->
       <dependency>
           <groupId>org.springframework.cloud</groupId>
           <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-ribbon</artifactId>
        </dependency>

(2)、修改application.yml文件 追加eureka的服務注冊地址

server:
  port: 80
  
eureka:
  client:
    register-with-eureka: false  #自己不能注冊自己
    service-url: 
      defaultZone: http://eureka7001.com:7001/eureka/,http://eureka7002.com:7002/eureka/,http://eureka7003.com:7003/eureka/

(3)良拼、對ConfigBean進行添加新注解@Load Balanced 獲得Rest時加入Ribbon的配置

@Configuration   //配置類战得,類似spring里面的applicationContext.xml
public class ConfigBean {

    /**
     * RestTemplate提供了多種便捷訪問遠程Http服務的方法
      *     是一種簡單便捷的訪問restful服務模板類,是Spring提供的用于訪問Rest服務的客戶端模板工具集
      *    使用restTemplate訪問restful接口非常的簡單粗暴無腦庸推。
     *  (url, requestMap, ResponseBean.class)這三個參數分別代表 
     *  REST請求地址常侦、請求參數、HTTP響應轉換被轉換成的對象類型予弧。
     */
    @Bean //注入bean
    @LoadBalanced //Spring Cloud Ribbon是基于Netflix Ribbon實現(xiàn)的一套客戶端,負載均衡的工具刮吧。 開啟負載均衡
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
}

(4)、主啟動類DeptConsumer80_App.java添加注解@EnableEurekaClient

@SpringBootApplication
@EnableEurekaClient
public class DeptConsumer80_App {   
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer80_App.class, args);
    }
}

(5)掖蛤、修改DeptController_Consumer.java客戶端訪問類

package com.smilexl.springcloud.controller;

import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import org.springframework.web.client.RestTemplate;
import com.smilexl.springcloud.entities.Dept;

@RestController
public class DeptController_Consumer {
    
    /**
     * RestTemplate提供了多種便捷訪問遠程Http服務的方法
      *   是一種簡單便捷的訪問restful服務模板類杀捻,是Spring提供的用于訪問Rest服務的客戶端模板工具集
      *   使用restTemplate訪問restful接口非常的簡單粗暴無腦。
     *  (url, requestMap, ResponseBean.class)這三個參數分別代表 
     *  REST請求地址蚓庭、請求參數致讥、HTTP響應轉換被轉換成的對象類型。
     */
    
//  private static final String REST_URL_PREFIX = "http://localhost:8001";
    private static final String REST_URL_PREFIX = "http://SERVICESPRINGCLOUD-DEPT";  //改為微服務名字

    @Autowired
    private RestTemplate restTemplate;

    // 添加
    @GetMapping("/consumer/dept/add")
    public Boolean add(Dept dept) {
        return restTemplate.postForObject(REST_URL_PREFIX + "/dept/add", dept, Boolean.class);
    }

    // 根據id查詢
    @GetMapping("/consumer/dept/get/{id}")
    public Dept get(@PathVariable("id") Long id) {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/get/" + id, Dept.class);
    }

    // 根據id查詢
    @SuppressWarnings("unchecked")
    @GetMapping("/consumer/dept/list")
    public List<Dept> list() {
        return restTemplate.getForObject(REST_URL_PREFIX + "/dept/list", List.class);
    }
}

(6)器赞、先啟動3個eureka集群垢袱,再啟動microservicecloud-provider-dept-8001并注冊進eureka

(7)、啟動microservicecloud-consumer-dept-80港柜,測試

(8)请契、小總結

Ribbon和Rureka整合后Cousumer可以直接調用服務而不用再關心地址和端口號


二咳榜、Ribbon負載均衡

1、架構說明

Ribbon在工作時分成兩步
? 第一步先選擇Eureka Server爽锥,它優(yōu)先選擇在同一個區(qū)域內負載較少的server涌韩,
? 第二步再根據用戶指定的策略,在從server取到的服務注冊列表中選擇一個地址氯夷,
? 其中Ribbon提供了多種策略:比如輪詢臣樱、隨機和根據響應時間加權。

2腮考、參考microservicecloud-provider-dept-8001雇毫,新建8002、8003
  • pom.xml文件中添加如下依賴
  <dependencies>
        <dependency><!-- 引入自己定義的api通用包踩蔚,可以使用Dept部門Entity -->
            <groupId>cn.smilexl.springcloud</groupId>
            <artifactId>microservicecloud-api</artifactId>
            <version>${project.version}</version>
        </dependency>

        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
        </dependency>
        <dependency>
            <groupId>mysql</groupId>
            <artifactId>mysql-connector-java</artifactId>
        </dependency>
        <dependency>
            <groupId>com.alibaba</groupId>
            <artifactId>druid</artifactId>
        </dependency>
        <dependency>
            <groupId>ch.qos.logback</groupId>
            <artifactId>logback-core</artifactId>
        </dependency>
        <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-jetty</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-web</artifactId>
        </dependency>
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-test</artifactId>
        </dependency>
        
        <!-- 將微服務provider注冊進eureka -->
        <dependency>
            <groupId>org.springframework.cloud</groupId>
            <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
        </dependency>
        <!-- actuator監(jiān)控信息完善 -->
        <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-actuator</artifactId>
        </dependency>
    </dependencies>
3棚放、新建8002、8003數據庫寂纪,各微服務分別連自己的數據庫
  • 8002 SQL腳本
DROP DATABASE IF EXISTS cloudDB02;
CREATE DATABASE cloudDB02 CHARACTER SET UTF8;
USE cloudDB02;
CREATE TABLE `dept` (
  `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) DEFAULT NULL,
  `db_source` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

INSERT INTO `dept` VALUES ('1', '開發(fā)部', 'clouddb01');
INSERT INTO `dept` VALUES ('2', '人事部', 'clouddb01');
INSERT INTO `dept` VALUES ('3', '財務部', 'clouddb01');
INSERT INTO `dept` VALUES ('4', '市場部', 'clouddb01');
INSERT INTO `dept` VALUES ('5', '運維部', 'clouddb01');
INSERT INTO `dept` VALUES ('6', '資訊部', 'clouddb01');
  • 8003 SQL腳本
DROP DATABASE IF EXISTS cloudDB03;
CREATE DATABASE cloudDB03 CHARACTER SET UTF8;
USE cloudDB03;
CREATE TABLE `dept` (
  `deptno` bigint(20) NOT NULL AUTO_INCREMENT,
  `dname` varchar(60) DEFAULT NULL,
  `db_source` varchar(60) DEFAULT NULL,
  PRIMARY KEY (`deptno`)
) ENGINE=InnoDB AUTO_INCREMENT=8 DEFAULT CHARSET=utf8;

INSERT INTO `dept` VALUES ('1', '開發(fā)部', 'clouddb01');
INSERT INTO `dept` VALUES ('2', '人事部', 'clouddb01');
INSERT INTO `dept` VALUES ('3', '財務部', 'clouddb01');
INSERT INTO `dept` VALUES ('4', '市場部', 'clouddb01');
INSERT INTO `dept` VALUES ('5', '運維部', 'clouddb01');
INSERT INTO `dept` VALUES ('6', '資訊部', 'clouddb01');
4席吴、修改8002、8003各子的yml
  • 8002 的yml
server:
  port: 8002
  
mybatis:
#  config-location: classpath:mybatis/mybatis.cfg.xml       # mybatis配置文件所在路徑
  type-aliases-package: cn.smilexl.springcloud.entities     # 所有Entity別名類所在包
  mapper-locations: classpath:mapper/**/*.xml               # mapper映射文件
    
spring:
   application:
    name: microservicecloud-dept                           # 微服務名
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 當前數據源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://47.99.218.123:3306/clouddb02          # 數據庫名稱
    username: root
    password: 123456
    dbcp2:
      min-idle: 5                                           # 數據庫連接池的最小維持連接數
      initial-size: 5                                       # 初始化連接數
      max-total: 5                                          # 最大連接數
      max-wait-millis: 200                                  # 等待連接獲取的最大超時時間
      
eureka:
  client: #客戶端注冊進eureka服務列表內
    service-url: 
#      defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
  instance:
    instance-id: microservicecloud-dept-8002  #自定義服務名稱信息
    prefer-ip-address: true  #訪問路徑可以顯示IP地址
 
#點擊超鏈接后顯示信息   
info:
  app.name: microservicecloud
  company.name: www.smilexl.cn
  build.artifactId: $project.artifactId$
  build.version: $project.version$
   
  • 8003 的yml
server:
  port: 8003
  
mybatis:
#  config-location: classpath:mybatis/mybatis.cfg.xml       # mybatis配置文件所在路徑
  type-aliases-package: cn.smilexl.springcloud.entities     # 所有Entity別名類所在包
  mapper-locations: classpath:mapper/**/*.xml               # mapper映射文件
    
spring:
   application:
    name: microservicecloud-dept                           # 微服務名
   datasource:
    type: com.alibaba.druid.pool.DruidDataSource            # 當前數據源操作類型
    driver-class-name: org.gjt.mm.mysql.Driver              # mysql驅動包
    url: jdbc:mysql://47.99.218.123:3306/clouddb03          # 數據庫名稱
    username: root
    password: 123456
    dbcp2:
      min-idle: 5                                           # 數據庫連接池的最小維持連接數
      initial-size: 5                                       # 初始化連接數
      max-total: 5                                          # 最大連接數
      max-wait-millis: 200                                  # 等待連接獲取的最大超時時間
      
eureka:
  client: #客戶端注冊進eureka服務列表內
    service-url: 
#      defaultZone: http://localhost:7001/eureka
      defaultZone: http://eureka7001.com:7001/eureka,http://eureka7002.com:7002/eureka,http://eureka7003.com:7003/eureka
  instance:
    instance-id: microservicecloud-dept-8003  #自定義服務名稱信息
    prefer-ip-address: true  #訪問路徑可以顯示IP地址
 
 #點擊超鏈接后顯示信息   
info:
  app.name: microservicecloud
  company.name: www.smilexl.cn
  build.artifactId: $project.artifactId$
  build.version: $project.version$
  

注意:

5捞蛋、啟動3個Dept微服務并且各自測試通過
  http://localhost:8001/dept/list
  http://localhost:8002/dept/list
  http://localhost:8003/dept/list
6、啟動 microservicecloud-consumer-dept-80
  http://localhost/consumer/dept/list

客戶端通過Ribbon完成負載均衡柬姚。注意觀看返回的數據庫名字拟杉,各不相同,負載均衡實現(xiàn)

7量承、總結

?? Ribbon其實就是一個負載均衡的客戶端組件搬设,他可以和其他所需要請求的客戶端結合使用,和eureka結合只是其中的一個實例撕捍。

三拿穴、Ribbon核心組件IRule

IRule:根據特定算法中從服務列表中選取一個要訪問的服務

  • RoundRobinRule:輪詢;
  • RandomRule:隨機忧风;
  • AvailabilityFilteringRule:會過濾掉由于多次訪問故障而處于斷路器跳閘狀態(tài)的服務默色,還有并發(fā)的連接數量超過閾值的服務,然后對剩余的服務列表按照輪詢策略進行訪問狮腿;
  • WeightedResponseTimeRule: 根據平均響應時間計算所有服務的權重腿宰,響應時間越快服務權重越大被選中的概率越高。剛啟動時如果統(tǒng)計信息不足缘厢,則使用RoundTobinRule策略吃度,等統(tǒng)計信息足夠會切換到WeightedResponseTimeRule;
  • RetryRule: 先按照RoudRobinRule的策略獲取服務贴硫,如果獲取服務失敗則在指定時間內進行重試椿每,獲取可用服務,如果還是失敗的就會自動把這個失敗的服務隔離掉;
  • BestAvailableRule: 會先過濾掉由于多次訪問故障而處于斷路器跳閘狀態(tài)的服務,然后選擇一個并發(fā)量小的服務间护;
  • ZoneAvoidanceRule: 默認規(guī)則亦渗,復合判斷server所在區(qū)域的性能和server的可用性選擇服務器;

修改Ribbon的算法:修改 microservicecloud-consumer-dept-80 中 /cfgbeans/ConfigBean.java文件

@Configuration   //配置類兑牡,類似spring里面的applicationContext.xml
public class ConfigBean {
    /**
     * RestTemplate提供了多種便捷訪問遠程Http服務的方法
      *     是一種簡單便捷的訪問restful服務模板類央碟,是Spring提供的用于訪問Rest服務的客戶端模板工具集
      *    使用restTemplate訪問restful接口非常的簡單粗暴無腦。
     *  (url, requestMap, ResponseBean.class)這三個參數分別代表 
     *  REST請求地址均函、請求參數亿虽、HTTP響應轉換被轉換成的對象類型。
     */
    @Bean //注入bean
    @LoadBalanced //Spring Cloud Ribbon是基于Netflix Ribbon實現(xiàn)的一套客戶端,負載均衡的工具苞也。 開啟負載均衡
    public RestTemplate getRestTemplate() {
        return new RestTemplate();
    }
    
    @Bean
    public IRule myRule() {
        return new RandomRule();//達到的目的:用我們從新選擇的隨機算法代替默認的輪詢算法
    }
    
}
//相對于洛勉,<bean id="restTemplate" class="com.smilexl.springcloud.cfgbean.RestTemplate">
    

四、Ribbon 自定義算法

1如迟、在 microservicecloud-consumer-dept-80 主啟動類上添加 @RibbonClient
package cn.smilexl.springcloud;

import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.cloud.netflix.eureka.EnableEurekaClient;
import org.springframework.cloud.netflix.ribbon.RibbonClient;
import cn.smilexl.myrule.MyselfRule;

@SpringBootApplication
@EnableEurekaClient
//在啟動該微服務的時候就能去加載我們的自定義Ribbon配置類收毫,從而使配置生效。
@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MyselfRule.class)
public class DeptConsumer80_App {
    
    public static void main(String[] args) {
        SpringApplication.run(DeptConsumer80_App.class, args);
    }
}

@RibbonClient(name="MICROSERVICECLOUD-DEPT",configuration=MyselfRule.class)

  • name:微服務的名字
  • configuration:自定義的算法類
    意思:對微服務 MICROSERVICECLOUD-DEPT殷勘,使用 MyselfRule.java類中的規(guī)則

注意配置事項: 這個自定義類(MyselfRule.java)不能放在@ComponentScan(即:主啟動類)所掃描的當前包下以及子包下此再,否則我們自定義的這個配置類就會被所有的Ribbon客戶端所共享,達不到特殊化定制的目的了玲销。

2输拇、步驟

(1)、新建package cn.smilexl.myrule 包

(2)贤斜、在此包下新建自定義Ribbon規(guī)則類 MyselfRule.java

package cn.smilexl.myrule;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;
import com.netflix.loadbalancer.RandomRule;

@Configuration
public class MyselfRule {
    
    @Bean
    public IRule myRule() {
        return new RandomRule();//Ribbon默認為輪詢策吠,自定義為隨機
    }
}
3、Ribbon自定義規(guī)則深度解析

需求:依舊輪詢策略瘩绒,但是加上新需求猴抹,每個服務器要求被調用5次。也即以前是每臺機器一次锁荔,現(xiàn)在是每臺機器5次蟀给。

解析源碼:https://github.com/Netflix/ribbon/blob/master/ribbon-loadbalancer/src/main/java/com/netflix/loadbalancer/RandomRule.java

參考源碼修改為需求要求的 RoundRobinRule_LL

(1)、參考源碼修改為需要的算法策略(RoundRobinRule_LL.java)

package cn.smilexl.myrule;

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;

/**
 * 自定義需求規(guī)則類
 *  --依舊輪詢策略堕战,但是加上新需求坤溃,每個服務器要求被調用5次。也即以前是每臺機器一次嘱丢,現(xiàn)在是每臺機器5次
 */

public class RoundRobinRule_LL extends AbstractLoadBalancerRule {

    /**
     * Randomly choose from all living servers
     */
    
    private int total = 0; //總共被調用的次數薪介,目前要求每臺被調用5次
    private int currentIndex = 0; //當前提供服務的機器號
    
    @SuppressWarnings("unused")
    public 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();
            List<Server> allList = lb.getAllServers();

            int serverCount = allList.size();
            if (serverCount == 0) {
                /*
                 * No servers. End regardless of pass, because subsequent passes
                 * only get more restrictive.
                 */
                return null;
            }

//            int index = chooseRandomInt(serverCount);
//            server = upList.get(index);   
            //定義判斷規(guī)則
            if(total < 5) {
                server = upList.get(currentIndex); //獲取當前的服務器
                total++;
            }else {
                total = 0;
                currentIndex++;
                if (currentIndex >= upList.size()) {//當前下標是否大于服務器總數
                    currentIndex = 0;
                }
            }

            if (server == null) {
                /*
                 * The only time this should happen is if the server list were
                 * somehow trimmed. This is a transient condition. Retry after
                 * yielding.
                 */
                Thread.yield();
                continue;
            }

            if (server.isAlive()) {
                return (server);
            }

            // Shouldn't actually happen.. but must be transient or a bug.
            server = null;
            Thread.yield();
        }

        return server;
    }

    @Override
    public Server choose(Object key) {
        return choose(getLoadBalancer(), key);
    }
    
    @Override
    public void initWithNiwsConfig(IClientConfig arg0) {
        // TODO Auto-generated method stub
    }
}

(2)、在配置類中注入自定義的算法策略(MyselfRule.java)

package cn.smilexl.myrule;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import com.netflix.loadbalancer.IRule;

@Configuration
public class MyselfRule {
    
    @Bean
    public IRule myRule() {
//      return new RandomRule();//Ribbon默認為輪詢越驻,自定義為隨機
//      return new RoundRobinRule();//輪詢
        return new RoundRobinRule_LL(); //調用自定義的算法規(guī)則汁政,每臺輪詢調用5次
    }
}

(3)道偷、最終工程目錄結構如下:

(4)、依次啟動工程并測試結果

依次啟動工程:
microservicecloud-eureka-7001记劈;
microservicecloud-eureka-7002勺鸦;
microservicecloud-eureka-7003;
microservicecloud-provider-dept-8001目木;
microservicecloud-provider-dept-8002换途;
microservicecloud-provider-dept-8003;
microservicecloud-consumer-dept-80刽射;

測試:localhost/consumer/dept/get/1

最后編輯于
?著作權歸作者所有,轉載或內容合作請聯(lián)系作者
  • 序言:七十年代末军拟,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子誓禁,更是在濱河造成了極大的恐慌懈息,老刑警劉巖,帶你破解...
    沈念sama閱讀 218,525評論 6 507
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件摹恰,死亡現(xiàn)場離奇詭異辫继,居然都是意外死亡,警方通過查閱死者的電腦和手機俗慈,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 93,203評論 3 395
  • 文/潘曉璐 我一進店門姑宽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人闺阱,你說我怎么就攤上這事低千。” “怎么了馏颂?”我有些...
    開封第一講書人閱讀 164,862評論 0 354
  • 文/不壞的土叔 我叫張陵,是天一觀的道長棋傍。 經常有香客問我救拉,道長,這世上最難降的妖魔是什么瘫拣? 我笑而不...
    開封第一講書人閱讀 58,728評論 1 294
  • 正文 為了忘掉前任亿絮,我火速辦了婚禮,結果婚禮上麸拄,老公的妹妹穿的比我還像新娘派昧。我一直安慰自己,他們只是感情好拢切,可當我...
    茶點故事閱讀 67,743評論 6 392
  • 文/花漫 我一把揭開白布蒂萎。 她就那樣靜靜地躺著,像睡著了一般淮椰。 火紅的嫁衣襯著肌膚如雪五慈。 梳的紋絲不亂的頭發(fā)上纳寂,一...
    開封第一講書人閱讀 51,590評論 1 305
  • 那天痛阻,我揣著相機與錄音鸟召,去河邊找鬼。 笑死窒朋,一個胖子當著我的面吹牛争拐,可吹牛的內容都是我干的腋粥。 我是一名探鬼主播,決...
    沈念sama閱讀 40,330評論 3 418
  • 文/蒼蘭香墨 我猛地睜開眼架曹,長吁一口氣:“原來是場噩夢啊……” “哼隘冲!你這毒婦竟也來了?” 一聲冷哼從身側響起音瓷,我...
    開封第一講書人閱讀 39,244評論 0 276
  • 序言:老撾萬榮一對情侶失蹤对嚼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個月后绳慎,有當地人在樹林里發(fā)現(xiàn)了一具尸體纵竖,經...
    沈念sama閱讀 45,693評論 1 314
  • 正文 獨居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內容為張勛視角 年9月15日...
    茶點故事閱讀 37,885評論 3 336
  • 正文 我和宋清朗相戀三年杏愤,在試婚紗的時候發(fā)現(xiàn)自己被綠了靡砌。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,001評論 1 348
  • 序言:一個原本活蹦亂跳的男人離奇死亡珊楼,死狀恐怖通殃,靈堂內的尸體忽然破棺而出,到底是詐尸還是另有隱情厕宗,我是刑警寧澤画舌,帶...
    沈念sama閱讀 35,723評論 5 346
  • 正文 年R本政府宣布,位于F島的核電站已慢,受9級特大地震影響曲聂,放射性物質發(fā)生泄漏。R本人自食惡果不足惜佑惠,卻給世界環(huán)境...
    茶點故事閱讀 41,343評論 3 330
  • 文/蒙蒙 一朋腋、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧膜楷,春花似錦旭咽、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,919評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至察蹲,卻和暖如春请垛,著一層夾襖步出監(jiān)牢的瞬間催训,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,042評論 1 270
  • 我被黑心中介騙來泰國打工宗收, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留漫拭,地道東北人。 一個月前我還...
    沈念sama閱讀 48,191評論 3 370
  • 正文 我出身青樓混稽,卻偏偏與公主長得像采驻,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子匈勋,可洞房花燭夜當晚...
    茶點故事閱讀 44,955評論 2 355

推薦閱讀更多精彩內容