照例附上項目github連接java
本項目實現的是將一個簡單的天氣預報系統一步一步改形成一個SpringCloud微服務系統的過程,本節主要講的是單塊架構改形成微服務架構的過程,最終將原來單塊架構的天氣預報服務拆分爲四個微服務:城市數據API微服務,天氣數據採集微服務,天氣數據API微服務,天氣預報微服務。git
本章主要講解天氣數據API微服務的實現。github
對原來單塊架構的天氣預報服務進行改進,去除多餘的依賴,最終的pom文件以下:web
<?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> <groupId>com.demo</groupId> <artifactId>sifoudemo02</artifactId> <version>0.0.1-SNAPSHOT</version> <packaging>jar</packaging> <name>sifoudemo02</name> <description>Demo project for Spring Boot</description> <parent> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-parent</artifactId> <version>2.0.5.RELEASE</version> <relativePath/> <!-- lookup parent from repository --> </parent> <properties> <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding> <project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding> <java.version>1.8</java.version> </properties> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-devtools</artifactId> <optional>true</optional> </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> <scope>test</scope> </dependency> <dependency> <groupId>org.slf4j</groupId> <artifactId>slf4j-jdk14</artifactId> <version>1.7.7</version> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-redis</artifactId> </dependency> </dependencies> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <configuration> <fork>true</fork> </configuration> <!-- <groupId>org.apache.felix</groupId> <artifactId>maven-bundle-plugin</artifactId> <extensions>true</extensions> --> </plugin> </plugins> </build> </project>
在service中保留以下接口:redis
(1)根據城市Id查詢天氣的接口getDataByCityIdspring
(2)根據城市名稱查詢天氣的接口getDataByCityNameapache
注意:原來咱們的天氣數據是先從緩存中獲取的,若查詢不到則調用第三方接口獲取天氣信息,並將其保存到緩存中。緩存
在咱們拆分紅微服務架構以後調用第三方接口的行爲由天氣數據採集微服務中的定時任務進行。架構
所以在天氣數據API微服務中咱們的天氣數據直接從緩存中進行獲取,若在緩存中獲取不到對應城市的數據,則直接拋出錯誤。app
@Service public class WeatherDataServiceImpl implements WeatherDataService { private final static Logger logger = LoggerFactory.getLogger(WeatherDataServiceImpl.class); private static final String WEATHER_URI = "http://wthrcdn.etouch.cn/weather_mini?"; @Autowired private StringRedisTemplate stringRedisTemplate; @Override public WeatherResponse getDataByCityId(String cityId) { String uri = WEATHER_URI + "citykey=" + cityId; return this.doGetWeahter(uri); } @Override public WeatherResponse getDataByCityName(String cityName) { String uri = WEATHER_URI + "city=" + cityName; return this.doGetWeahter(uri); } private WeatherResponse doGetWeahter(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"); // 緩存沒有,拋出異常 throw new RuntimeException("Don't has data!"); } try { resp = mapper.readValue(strBody, WeatherResponse.class); } catch (IOException e) { //e.printStackTrace(); logger.error("Error!",e); } return resp; } }
在controller中提供根據城市Id和名稱獲取天氣數據的接口。
@RestController @RequestMapping("/weather") public class WeatherController { @Autowired private WeatherDataService weatherDataService; @GetMapping("/cityId/{cityId}") public WeatherResponse getWeatherByCityId(@PathVariable("cityId") String cityId) { return weatherDataService.getDataByCityId(cityId); } @GetMapping("/cityName/{cityName}") public WeatherResponse getWeatherByCityName(@PathVariable("cityName") String cityName) { return weatherDataService.getDataByCityName(cityName); } }