前言
本系列文章將簡單的學習SpringCloud微服務相關知識,其實也是因爲時間的原因,一直拖到現在,遂打算趁着假期,決定記錄下來。
從天氣預報微服務系統的單體架構——>分佈式架構的演變過程中,一步一步,由淺及深的學習SpringCloud微服務的思想與其實現的組件。
本系列文章分爲以下幾個章節:
- SpringBoot搭建天氣預報微服務系統(單體架構)
- SpringBoot集成Redis緩存
- SpringBoot集成Quartz定時框架
- SpringBoot結合Thymeleaf模板與Bootstrap快速搭建界面
- 單體架構到微服務架構的拆分
- SpringCloud微服務組件—Eureka服務註冊與發現
- SpringCloud微服務組件—Feign負載均衡與高可用
- SpringCloud微服務組件—Zuul實現API網關分配
- SpringCloud微服務組件—Config集中實現配置管理
- SpringCloud微服務組件—Hystrix服務熔斷機制
項目源碼已上傳至Github.
開發環境
- JDK 1.8
- IDEA 2017.3
- Gradle 4
- HttpClient 4.5.3
- Redis 3.2
- SpringBoot 2.0.0.RELEASE
//依賴關係
dependencies {
//該依賴用於編譯階段
compile('org.springframework.boot:spring-boot-starter-web')
//HttpClient
compile('org.apache.httpcomponents:httpclient:4.5.3')
//Redis
compile('org.springframework.boot:spring-boot-starter-data-redis')
//該依賴用於測試階段
testCompile('org.springframework.boot:spring-boot-starter-test')
}
爲什麼是Redis
我們知道Redis是一種key-value類型的緩存數據庫,是存儲在內存中的非關係型輕量級的數據庫。在日常的開發中,我們可以選擇一些資源數據來存入Redis中,以提高系統的流暢與併發性。
而在天氣預報系統中,我們知道天氣數據其實並不是每時每刻的在更新的。如果你留心觀察,你會發現,它們是以每半小時或者一小時的頻率來進行更新的。如果我們將天氣數據存入緩存中,每次調用API時,首先查詢本地緩存中是否存在天氣數據,假如存在,就從Redis的緩存中去請取;如果不存在,那我們再調用第三方藉口提供的API就行查詢,並將數據存入Redis中,方便下次請求調用。
如何加入Redis
WeatherDataServiceImpl
在我們之前的項目基礎上進行添加與修改。
@Service
public class WeatherDataServiceImpl implements WeatherDataService {
private static final Logger logger = LoggerFactory.getLogger(WeatherDataServiceImpl.class);
private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?";
private static final long TIME_OUT = 1800L;//1800s
@Autowired
private RestTemplate restTemplate;
@Autowired
private StringRedisTemplate stringRedisTemplate;
@Override
public WeatherResponse getDataByCityId(String cityId) {
String uri = WEATHER_URI + "citykey=" + cityId;
return this.doGetWeather(uri);
}
@Override
public WeatherResponse getDataByCityName(String cityName) {
String uri = WEATHER_URI + "city=" + cityName;
return this.doGetWeather(uri);
}
/**
* 重構代碼
* @param uri
* @return
*/
private WeatherResponse doGetWeather(String uri) {
String key = uri;
String strBody = null;
ObjectMapper mapper = new ObjectMapper();
WeatherResponse resp = null;
ValueOperations<String, String> ops = stringRedisTemplate.opsForValue();
//先查緩存,如果緩存中有天氣信息就在緩存中取
if (stringRedisTemplate.hasKey(key)) {
logger.info("Redis has data");
strBody = ops.get(key);
} else {
logger.info("Redis don't has data");
//如果緩存沒有,再去調用服務接口來獲取
ResponseEntity<String> respString = restTemplate.getForEntity(uri,String.class);
//將接口返回的Json字符串轉換成對象
if (respString.getStatusCodeValue() == 200) {
strBody = respString.getBody();
}
//數據寫入緩存
ops.set(uri,strBody,TIME_OUT, TimeUnit.SECONDS);
}
try {
resp = mapper.readValue(strBody,WeatherResponse.class);
} catch (IOException e) {
logger.info("Error!!",e);
}
return resp;
}
}
運行
輸入http://localhost:8080/weather/cityId/101280601
,運行。
可以知道,
第一次查詢Redis中是沒有數據的,日誌打印logger.info("Redis don't has data");
之後的查詢中,數據已經存在於本地緩存中,日誌打印logger.info("Redis has data");
我們通過Redis Desktop Manager也可以看到,緩存於Redis中的數據。
以上,我們就集成了Redis到了天氣預報系統中,接下來我們將集成Quartz定時任務框架,來定時的調用緩存服務。