SpringBoot整合Redis實(shí)現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解 天天頭條
時(shí)間:2023-06-24 16:03:49
目錄
什么是緩存為什么要用緩存Redis為什么這么快實(shí)現(xiàn)一個(gè)用戶信息的緩存方式一:利用RedisTemplate實(shí)現(xiàn) 導(dǎo)入依賴添加配置添加redis工具類及配置類service層controller層測(cè)試方式二:采用SpringBoot注解開啟緩存修改service層實(shí)現(xiàn)類代碼修改RedisConfig配置類什么是緩存
緩存是?個(gè)高速數(shù)據(jù)交換的存儲(chǔ)器,使用它可以快速的訪問(wèn)和操作數(shù)據(jù)。
舉個(gè)通俗的例子。
小明經(jīng)營(yíng)著一家飯店,在剛開張的時(shí)候由于名氣不足,客源少,生意并不是很忙,平時(shí)沒(méi)事的時(shí)候就閑著,有客人來(lái)了再進(jìn)廚房安排做菜。隨著飯店的日益發(fā)展,此時(shí)的飯店已經(jīng)不同往日,有著大量的穩(wěn)定客源,并且在某些節(jié)假日的時(shí)候甚至爆滿。按照以前的做法,那肯定是行不通了,在用餐高峰期的時(shí)候因?yàn)閭洳吐龑?dǎo)致了客戶的長(zhǎng)時(shí)間等待,使得飯店的屢遭投訴。
為解決這一問(wèn)題,小明想到了一個(gè)辦法,可以在空閑的時(shí)候,提前將熱門的菜做完后放入保溫柜,等用餐高峰期時(shí)再拿出來(lái)加熱后就可以直接上菜,就規(guī)避了短時(shí)間內(nèi)大量客源而導(dǎo)致的備餐慢的問(wèn)題,通過(guò)這一方法,即使在高峰期,也能很好的應(yīng)對(duì)。
(資料圖片)
這就是緩存的本質(zhì),將熱點(diǎn)資源(高頻讀、低頻寫)提前放入離用戶最近、訪問(wèn)速度更快的地方,以提高訪問(wèn)速度。
為什么要用緩存
使用緩存后,效率會(huì)大大的提升,減少了不必要的資源消耗,提升了用戶體驗(yàn)。
redis的特點(diǎn):
redis支持?jǐn)?shù)據(jù)的持久化,可以將內(nèi)存中的數(shù)據(jù)保存在磁盤中,重啟的時(shí)候可以再次加在進(jìn)行使用。redis不僅僅支持簡(jiǎn)單的key-value類型的數(shù)據(jù),同時(shí)還提供list,set,zset,hash等數(shù)據(jù)結(jié)構(gòu)的儲(chǔ)存redis支持?jǐn)?shù)據(jù)的備份,即master-slave模式的數(shù)據(jù)備份redis的優(yōu)勢(shì):
性能極高——redis能讀得的速度是110000次/s,寫的速度是81000次/s。豐富的數(shù)據(jù)類型——redis支持二進(jìn)制案例的Strings, Lists, Hashes, Sets 及 Ordered Sets 數(shù)據(jù)類型操作。原子——redis的所有操作都是原子性的,意思就是要么成功執(zhí)行要么失敗完全不執(zhí)行。單個(gè)操作是原子性的。多個(gè)操作也支持事務(wù),即原子性,通過(guò)multi和exec指令包起來(lái)。豐富的特性redis還支持publish/subscribe,通知,key過(guò)期等等特性Redis為什么這么快
(1)完全基于內(nèi)存,數(shù)據(jù)存在內(nèi)存中,絕大部分請(qǐng)求是純粹的內(nèi)存操作,非常快速,跟傳統(tǒng)的磁盤文件數(shù)據(jù)存儲(chǔ)相比,避免了通過(guò)磁盤IO讀取到內(nèi)存這部分的開銷。
(2)數(shù)據(jù)結(jié)構(gòu)簡(jiǎn)單,對(duì)數(shù)據(jù)操作也簡(jiǎn)單。Redis中的數(shù)據(jù)結(jié)構(gòu)是專門進(jìn)行設(shè)計(jì)的,每種數(shù)據(jù)結(jié)構(gòu)都有一種或多種數(shù)據(jù)結(jié)構(gòu)來(lái)支持。Redis正是依賴這些靈活的數(shù)據(jù)結(jié)構(gòu),來(lái)提升讀取和寫入的性能。
(3)采用單線程,省去了很多上下文切換的時(shí)間以及CPU消耗,不存在競(jìng)爭(zhēng)條件,不用去考慮各種鎖的問(wèn)題,不存在加鎖釋放鎖操作,也不會(huì)出現(xiàn)死鎖而導(dǎo)致的性能消耗。
(4)使用基于IO多路復(fù)用機(jī)制的線程模型,可以處理并發(fā)的鏈接。
實(shí)現(xiàn)一個(gè)用戶信息的緩存
數(shù)據(jù)庫(kù)表結(jié)構(gòu):
CREATE TABLE `blade_user` ( `id` bigint(20) NOT NULL COMMENT "主鍵", `tenant_id` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT "000000" COMMENT "租戶ID", `code` varchar(12) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "用戶編號(hào)", `user_type` int(11) DEFAULT NULL COMMENT "用戶平臺(tái)", `account` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "賬號(hào)", `password` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "密碼", `name` varchar(20) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "昵稱", `real_name` varchar(10) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "真名", `avatar` varchar(500) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "頭像", `email` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "郵箱", `phone` varchar(45) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "手機(jī)", `birthday` datetime DEFAULT NULL COMMENT "生日", `sex` int(11) DEFAULT NULL COMMENT "性別", `role_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "角色id", `dept_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "部門id", `post_id` varchar(1000) CHARACTER SET utf8mb4 COLLATE utf8mb4_general_ci DEFAULT NULL COMMENT "崗位id", `create_user` bigint(20) DEFAULT NULL COMMENT "創(chuàng)建人", `create_dept` bigint(20) DEFAULT NULL COMMENT "創(chuàng)建部門", `create_time` datetime DEFAULT NULL COMMENT "創(chuàng)建時(shí)間", `update_user` bigint(20) DEFAULT NULL COMMENT "修改人", `update_time` datetime DEFAULT NULL COMMENT "修改時(shí)間", `status` int(11) DEFAULT NULL COMMENT "狀態(tài)", `is_deleted` int(11) DEFAULT "0" COMMENT "是否已刪除", PRIMARY KEY (`id`) USING BTREE ) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_general_ci ROW_FORMAT=DYNAMIC COMMENT="用戶表";
方式一:利用RedisTemplate實(shí)現(xiàn) 導(dǎo)入依賴
完整pom.xml文件:
4.0.0 org.springframework.boot spring-boot-starter-parent 2.7.8 com.redis.demo springboot-redis 0.0.1-SNAPSHOT springboot-redis Demo project for Spring Boot 1.8 org.springframework.boot spring-boot-starter-web org.projectlombok lombok true org.springframework.boot spring-boot-starter-test test com.baomidou mybatis-plus-boot-starter 3.4.2 org.springframework.boot spring-boot-starter-data-redis mysql mysql-connector-java 8.0.15 cn.hutool hutool-all 5.8.5 com.alibaba fastjson 1.2.41 org.springframework.boot spring-boot-starter-cache org.springframework.boot spring-boot-maven-plugin org.projectlombok lombok
添加配置
application.yml文件:
server:
port: 8081
spring:
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://3.129.36.183:3306/test?serverTimezone=GMT%2B8&useUnicode=true&characterEncoding=UTF-8
username: root
password: root
#redis
redis:
host: 3.129.36.183
#Redis服務(wù)器連接端口
port: 6379
#Redis服務(wù)器連接密碼
password: 123456
mybatis-plus:
configuration:
log-impl: org.apache.ibatis.logging.stdout.StdOutImpl #開啟sql日志
# 將帶有下劃線的表字段映射為駝峰格式的實(shí)體類屬性
map-underscore-to-camel-case: true
#配置類型別名所對(duì)應(yīng)的包
type-aliases-package: com.redis.demo.entity
#配置SQL輸出語(yǔ)句com.winsun.dataclean.mapper
mapper-locations: com/redis/demo/dao/*.xml
添加redis工具類及配置類
RedisUtils:
package com.redis.demo.utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Component;
import org.springframework.util.CollectionUtils;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.concurrent.TimeUnit;
/**
* Redis工具類
*
* @author
*/
@Component
public class RedisUtils {
@Autowired
private RedisTemplate redisTemplate;
// =============================common============================
/**
* 指定緩存失效時(shí)間
*
* @param key 鍵
* @param time 時(shí)間(秒)
* @return
*/
public boolean expire(String key, long time) {
try {
if (time > 0) {
redisTemplate.expire(key, time, TimeUnit.SECONDS);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 根據(jù)key 獲取過(guò)期時(shí)間
*
* @param key 鍵 不能為null
* @return 時(shí)間(秒) 返回0代表為永久有效
*/
public long getExpire(String key) {
return redisTemplate.getExpire(key, TimeUnit.SECONDS);
}
/**
* 判斷key是否存在
*
* @param key 鍵
* @return true 存在 false不存在
*/
public boolean hasKey(String key) {
try {
return redisTemplate.hasKey(key);
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 刪除緩存
*
* @param key 可以傳一個(gè)值 或多個(gè)
*/
@SuppressWarnings("unchecked")
public void del(String... key) {
if (key != null && key.length > 0) {
if (key.length == 1) {
redisTemplate.delete(key[0]);
} else {
redisTemplate.delete(CollectionUtils.arrayToList(key));
}
}
}
// ============================String=============================
/**
* 普通緩存獲取
*
* @param key 鍵
* @return 值
*/
public Object get(String key) {
return key == null ? null : redisTemplate.opsForValue().get(key);
}
/**
* 普通緩存放入
*
* @param key 鍵
* @param value 值
* @return true成功 false失敗
*/
public boolean set(String key, Object value) {
try {
redisTemplate.opsForValue().set(key, value);
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 普通緩存放入并設(shè)置時(shí)間
*
* @param key 鍵
* @param value 值
* @param time 時(shí)間(秒) time要大于0 如果time小于等于0 將設(shè)置無(wú)限期
* @return true成功 false 失敗
*/
public boolean set(String key, Object value, long time) {
try {
if (time > 0) {
redisTemplate.opsForValue().set(key, value, time, TimeUnit.SECONDS);
} else {
set(key, value);
}
return true;
} catch (Exception e) {
e.printStackTrace();
return false;
}
}
/**
* 遞增
*
* @param key 鍵
* @param delta 要增加幾(大于0)
* @return
*/
public long incr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞增因子必須大于0");
}
return redisTemplate.opsForValue().increment(key, delta);
}
/**
* 遞減
*
* @param key 鍵
* @param delta 要減少幾(小于0)
* @return
*/
public long decr(String key, long delta) {
if (delta < 0) {
throw new RuntimeException("遞減因子必須大于0");
}
return redisTemplate.opsForValue().increment(key, -delta);
}
// ================================Map=================================
/**
* HashGet
*
* @param key 鍵 不能為null
* @param item 項(xiàng) 不能為null
* @return 值
*/
public Object hget(String key, String item) {
return redisTemplate.opsForHash().get(key, item);
}
/**
* 獲取hashKey對(duì)應(yīng)的所有鍵值
*
* @param key 鍵
* @return 對(duì)應(yīng)的多個(gè)鍵值
*/
public MapRedisConfig:
package com.redis.demo.config;
import com.fasterxml.jackson.annotation.JsonAutoDetect;
import com.fasterxml.jackson.annotation.PropertyAccessor;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.redis.demo.utils.MapUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.interceptor.KeyGenerator;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.Jackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.RedisSerializer;
import javax.annotation.PostConstruct;
import java.util.Map;
/**
* @Author: laz
* @CreateTime: 2023-02-20 11:55
* @Version: 1.0
*
* 序列化
*/
@Configuration
public class RedisConfig {
@Autowired
private RedisTemplate redisTemplate;
@PostConstruct
public void init() {
initRedisTemplate();
}
private void initRedisTemplate() {
RedisSerializer stringSerializer = redisTemplate.getStringSerializer();
redisTemplate.setKeySerializer(stringSerializer);
redisTemplate.setHashKeySerializer(stringSerializer);
redisTemplate.setValueSerializer(stringSerializer);
redisTemplate.setHashValueSerializer(stringSerializer);
}
}
開發(fā)mapper接口
package com.redis.demo.dao; import com.baomidou.mybatisplus.core.mapper.BaseMapper; import com.redis.demo.entity.BladeUser; /** ** 用戶表 Mapper 接口 *
* * @author laz * @since 2023-03-09 */ public interface BladeUserMapper extends BaseMapper{ }
service層
IBladeUserService:
package com.redis.demo.service; import com.baomidou.mybatisplus.extension.service.IService; import com.redis.demo.entity.BladeUser; import com.redis.demo.result.DealResult; /** ** 用戶表 服務(wù)類 *
* * @author laz * @since 2023-03-09 */ public interface IBladeUserService extends IService{ DealResult getById(Long id); }
BladeUserServiceImpl:
package com.redis.demo.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.redis.demo.constant.RedisConstants; import com.redis.demo.dao.BladeUserMapper; import com.redis.demo.entity.BladeUser; import com.redis.demo.result.DealResult; import com.redis.demo.service.IBladeUserService; import com.redis.demo.status.CacheNameStatus; import com.redis.demo.utils.RedisUtils; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; /** ** 用戶表 服務(wù)實(shí)現(xiàn)類 *
* * @author laz * @since 2023-03-09 */ @Service public class BladeUserServiceImpl extends ServiceImplimplements IBladeUserService { @Autowired private RedisUtils redisUtils; @Override public DealResult getById(Long id) { String userKey = RedisConstants.CACHE_USER_KEY+id; Object user = redisUtils.get(userKey); if (!ObjectUtils.isEmpty(user)){ return DealResult.data(JSONUtil.toBean(JSONUtil.toJsonStr(user),BladeUser.class)); } BladeUser bladeUser = baseMapper.selectById(id); redisUtils.set(userKey, JSON.toJSONString(bladeUser)); return DealResult.data(bladeUser); } }
controller層
package com.redis.demo.controller; import com.redis.demo.result.DealResult; import com.redis.demo.service.IBladeUserService; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.web.bind.annotation.PathVariable; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.RestController; /** ** 用戶表 前端控制器 *
* * @author laz * @since 2023-03-09 */ @RestController @RequestMapping("/bladeUser") public class BladeUserController { @Autowired private IBladeUserService bladeUserService; @RequestMapping("getById/{id}") public DealResult getById(@PathVariable("id")Long id){ return bladeUserService.getById(id); } }
測(cè)試
啟動(dòng)項(xiàng)目,使用postman訪問(wèn)該接口,連續(xù)請(qǐng)求兩次,觀察響應(yīng)時(shí)長(zhǎng):
第一次:
第二次:
可以看到,第一次3.34s,第二次43ms,效率明顯提高!
方式二:采用SpringBoot注解開啟緩存
以方式一為準(zhǔn)
在啟動(dòng)類添加@EnableCaching注解
修改service層實(shí)現(xiàn)類代碼
package com.redis.demo.service.impl; import cn.hutool.core.bean.BeanUtil; import cn.hutool.json.JSONUtil; import com.alibaba.fastjson.JSON; import com.alibaba.fastjson.JSONObject; import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl; import com.redis.demo.constant.RedisConstants; import com.redis.demo.dao.BladeUserMapper; import com.redis.demo.entity.BladeUser; import com.redis.demo.result.DealResult; import com.redis.demo.service.IBladeUserService; import com.redis.demo.status.CacheNameStatus; import com.redis.demo.utils.RedisUtils; import lombok.AllArgsConstructor; import org.springframework.beans.BeanUtils; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.cache.annotation.Cacheable; import org.springframework.stereotype.Service; import org.springframework.util.ObjectUtils; /** ** 用戶表 服務(wù)實(shí)現(xiàn)類 *
* * @author laz * @since 2023-03-09 */ @Service public class BladeUserServiceImpl extends ServiceImplimplements IBladeUserService { @Autowired private RedisUtils redisUtils; // @Override // public DealResult getById(Long id) { // // String userKey = RedisConstants.CACHE_USER_KEY+id; // Object user = redisUtils.get(userKey); // if (!ObjectUtils.isEmpty(user)){ // // return DealResult.data(JSONUtil.toBean(JSONUtil.toJsonStr(user),BladeUser.class)); // } // // BladeUser bladeUser = baseMapper.selectById(id); // redisUtils.set(userKey, JSON.toJSONString(bladeUser)); // return DealResult.data(bladeUser); // } @Cacheable(cacheNames = CacheNameStatus.BLADE_USER,keyGenerator = CacheNameStatus.KEY_GENERATOR) @Override public DealResult getById(Long id) { BladeUser bladeUser = baseMapper.selectById(id); return DealResult.data(bladeUser); } }
修改RedisConfig配置類
在配置類中添加自定義KeyGenerator
/**
* 自定義KeyGenerator
* @return
*/
@Bean
public KeyGenerator simpleKeyGenerator() {
return (o, method, objects) -> {
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append(o.getClass().getSimpleName());
stringBuilder.append(".");
stringBuilder.append(method.getName());
stringBuilder.append("[");
for (Object obj : objects) {
if(obj.toString().indexOf("Vo@")!= -1)
{
Map map = MapUtil.getAttrFromModel(obj);
stringBuilder.append("[");
for(String item:map.keySet())
{
stringBuilder.append(",");
stringBuilder.append(map.get(item));
}
stringBuilder.append(",");
stringBuilder.deleteCharAt(stringBuilder.length() - 1);
stringBuilder.append("]");
}
else {
stringBuilder.append(obj);
stringBuilder.append(",");
}
}
stringBuilder.append("]");
return stringBuilder.toString();
};
}
注:關(guān)于 @Cacheable注解的參數(shù),不懂的可以點(diǎn)擊查看。
重啟項(xiàng)目,再次訪問(wèn)以上接口,觀察響應(yīng)時(shí)間:
第一次:
第二次:
可以看到,第一次2.52s,第二次44ms,效率明顯提高!
通過(guò)Redis可視化工具觀察緩存數(shù)據(jù):
通過(guò)觀察緩存數(shù)據(jù)大小可知:方式一449字節(jié),方式二976字節(jié),如果從內(nèi)存占用大小的角度考慮,博主認(rèn)為使用RedisTemplate方式做緩存更合適,因?yàn)檫@種方式所占內(nèi)存相對(duì)較少。
以上就是該篇文章的所有內(nèi)容,代碼已上傳至git:https://gitee.com/lianaozhe/springboot-redis.git
到此這篇關(guān)于SpringBoot整合Redis實(shí)現(xiàn)高并發(fā)數(shù)據(jù)緩存的文章就介紹到這了,更多相關(guān)SpringBoot Redis高并發(fā)數(shù)據(jù)緩存內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)稿件
SpringBoot整合Redis實(shí)現(xiàn)高并發(fā)數(shù)據(jù)緩存的示例講解 天天頭條
全球看熱訊:古裝廠牌到全能玩家,年均爆款的西嘻影業(yè)提供了影視公司的生存法
【旗艦】7.5見?紅魔8S Pro發(fā)布時(shí)間曝光 國(guó)內(nèi)首臺(tái)8G2超頻版 全球百事通
廈門社保要交滿多少年,廈門社保繳費(fèi)年限如何法規(guī)的
烏克蘭基輔市遭導(dǎo)彈襲擊 已致3人死亡_焦點(diǎn)信息
世界新資訊:北京市氣象臺(tái)發(fā)布高溫紅色預(yù)警信號(hào) 最高氣溫可達(dá)37-40℃
世界信息:上海2022年退休工資調(diào)整細(xì)則
萬(wàn)圣節(jié)門鈴和禮物創(chuàng)意,男生浪漫到底可行嗎?如何為這個(gè)節(jié)日增添驚喜?知乎專家來(lái)為你解答!
風(fēng)吹十里荷花香 “蓮”通鄉(xiāng)村“致富路”
美媒稱波蘭曾作為“北溪”爆炸行動(dòng)基地 波蘭:完全不屬實(shí)!
世界新動(dòng)態(tài):全國(guó)鐵路今天預(yù)計(jì)發(fā)送旅客1515萬(wàn)人次
燃?xì)忾y門怎樣操作,你都了解嗎?請(qǐng)收藏轉(zhuǎn)發(fā)!
全球資訊:三天漲超20%!工業(yè)富聯(lián)最新發(fā)聲
速遞!白玉蘭視帝視后出爐,雷佳音打敗張譯獲得視帝,吳越視后實(shí)至名歸
六月第4期:六大策略組合表現(xiàn):寬信用本周收益率為0.5%
保護(hù)知識(shí)產(chǎn)權(quán)激發(fā)創(chuàng)新活力
端午節(jié)了還沒(méi)學(xué)會(huì)包粽子?用VR試試,幫你成為特級(jí)廚師!
天天即時(shí)看!CK3歷史人物維基翻譯(166):弗沙塔將軍
環(huán)球今頭條!美媒:福特?cái)M進(jìn)行新一輪裁員,主要針對(duì)美國(guó)正式員工
端午假期廈門舉辦各式活動(dòng) 市民游客感受傳統(tǒng)節(jié)日魅力
廈門天馬高世代生產(chǎn)線項(xiàng)目順利推進(jìn)
我國(guó)最長(zhǎng)深水油氣管道進(jìn)入調(diào)試階段
教育頻道
廈門社保要交滿多少年,廈門社保繳費(fèi)年限如何法規(guī)的
安徽多地啟動(dòng)新一輪促消費(fèi)活動(dòng)_全球熱點(diǎn)
世界熱文:23071期大樂(lè)透曬票:生活充滿希望,努力前行就能越來(lái)越好
北京中考首日東直門中學(xué)考點(diǎn):工作人員用輪椅送崴腳考生進(jìn)考場(chǎng) 天天快資訊
海通國(guó)際:給予雙箭股份增持評(píng)級(jí),目標(biāo)價(jià)位11.6元 當(dāng)前速讀
世界熱文:深度體驗(yàn)“最孤獨(dú)城市”茫崖 旅行達(dá)人提議打造獨(dú)特IP


