天气数据采集微服务的实现:数据采集组件、数据存储组件
优采云 发布时间: 2022-05-25 13:07天气数据采集微服务的实现:数据采集组件、数据存储组件
. Spring Boot Data Redis Starter 2.0.0.M4。
.Redis 3.2.100。
. Spring Boot Quartz Starter 2.0.0.M4。
. Quartz Scheduler 2.3.0。
新增天气数据采集服务接口及实现
在
com.waylau.spring.cloud.weather.service包下,我们定义了该应用的天气数据采集服务接口WeatherDataCollectionService。
public interface WeatherDataCollectionService {<br />/**<br />*根据城市工D同步天气数据<br />*<br />*@param cityId<br />*@return<br />*/<br />void syncDataByCityId(String cityId);<br />}
WeatherDataCollectionService只有一个同步天气数据的方法。WeatherDataCollectionServicelmpl是对WeatherDataCollectionService接口的实现。
package com.waylau.spring.cloud.weather.service;<br />import java.util.concurrent.TimeUnit;<br />import org.slf4j.Logger;<br />import org.slf4j-LoggerFactory;<br />import org.springframework.beans.factory.annotation.Autowired;<br />import org.springframework.data.redis.core.StringRedisTemplate;<br />import org.springframework.data.redis.core.ValueOperations;<br />import org.springframework.http.ResponseEntity;<br />import org.springframework.stereotype.Service;<br />import org.springframework.web.client.RestTemplate;<br />/*★<br />*天气数据采集服务.<br />*<br />*@since 1.o.0 2017年10月29日<br />* @author Way Lau<br />*/<br />@service<br />public class WeatherDataCollectionServicelmpl implements WeatherData<br />CollectionService {<br />private final static Logger logger = LoggerFactory.getLogger(Weather<br />DatacollectionServicelmpl.class);<br />@Autowired<br />private RestTemplate restTemplate;<br />@Autowired<br />private stringRedisTemplate stringRedisTemplate;<br />private final String WEATHER_API = "http://wthrcdn.etouch.cn/weather_mini";<br />private final Long TIME_OUT = 1800L;//缓存超时时间<br />@override<br />public void syncDataByCityId(String cityId) {<br />logger.info ("Start同步天气.cityId: "+cityId);<br />String uri = WEATHER_API +"?citykey=" +cityId;<br />this.saveweatherData (uri);<br />logger.info("End同步天气");<br />private void saveWeatherData(String uri) {<br />ValueOperations ops= this.stringRedisTemplate.<br />opsForValue() ;<br />String key = uri;<br />String strBody = null;<br />ResponseEntity response = restTemplate.getForEntity(uri,<br />String.class);<br />if(response.getStatusCodeValue()=-200) f<br />strBody=response.getBody(;<br />ops.set(key,strBody,TIME_OUT,TimeUnit.SECONDS);<br />}<br />}
WeatherDataCollectionServiceImpl的实现过程,我们在之前的章节中也已经详细介绍过,大家也已经非常熟悉了。无非就是通过REST客户端去调用第三方的天气数据接口,并将返回的数据直接放入Redis存储中。
同时,我们需要设置Redis数据的过期时间。
修改天气数据同步任务
对于天气数据同步任务WeatherDataSyncJob,我们要做一些调整。把之前所依赖的CityData-Service、WeatherDataService改为
WeatherDataCollectionService。
import java.util.ArrayList;<br />import java.util.List;<br />import org.quartz.JobExecutionContext;<br />import org.quartz.JobExecutionException;<br />import org.slf4j-Logger;<br />import org.slf4j.LoggerFactory;<br />import org.springframework.beans.factory.annotation.Autowired;<br />import org.springframework.scheduling.quartz.QuartzJobBean;<br />import com.waylau.spring.cloud.weather.service.WeatherDataCollection<br />service;<br />import com.waylau.spring.cloud.weather.vo.City;<br />*★<br />天气数据同步任务.<br />*<br />*@since 1.0.0 2017年10月29日<br />* author <a href=span style="box-sizing: border-box;border-width: 0px;border-style: initial;border-color: initial;color: rgb(0, 117, 59);""https://waylau.com"/span>Way Lau</a><br />*/<br />public class WeatherDataSyncJob extends QuartzJobBean<br />private final static Logger logger = LoggerFactory.getLogger(Weather<br />DatasyncJob.class);<br />@Autowired<br />private WeatherDataCollectionService weatherDataCollectionService;<br />@override<br />protected void executeInternal (JobExecutionContext context) throws<br />JobExecutionException{<br />logger.info("'Start天气数据同步任务");<br />/TODO改为由城市数据API微服务来提供数据<br />工istcityList =null;<br />trY {<br />//TODO 调用城市数据APT<br />cityList = new ArrayEist();<br />City city = new City();<br />city.setCityId("101280601");<br />cityList.add(city);<br />}catch(Exception e){<br />logger.error("获取城市信息异常!",e);<br />throw new RuntimeException("获取城市信息异常!",e);<br />}<br />for(City city : cityList){<br />String cityld = city.getCityld(;<br />logger.info("天气数据同步任务中,cityId:" +cityId);<br />//根据城市ID同步天气数据<br />weatherDataCollectionService.syncDataByCityId(cityId);<br />logger.info("End 天气数据同步任务");<br />}<br />}
这里需要注意的是,定时器仍然对城市ID列表有依赖,只不过这个依赖最终会由其他应用(城市数据API微服务)来提供,所以这里暂时还没有办法完全写完,先用“TODO”来标识这个方法,后期还需要改进。但为了能让整个程序可以完整地走下去,我们在程序里面假设返回了一个城市ID为“101280601”的城市信息。
配置类
配置类仍然保留之前的RestConfiguration、QuartzConfiguration的代码不变,如下所示。
1.RestConfiguration
RestConfiguration用于配置REST客户端。
import org.springframework.beans.factory.annotation.Autowired;<br />import org.springframework.boot.web.client.RestTemplateBuilder;<br />import org.springframework.context.annotation.Bean;<br />import org.springframework.context.annotation.Configuration;<br />import org.springframework.web.client.RestTemplate;<br />/**<br />*REST 配置类.<br />*<br />*@since 1.0.0 2017年10月18日<br />* @author Way Lau<br />*/<br />@configuration<br />public class RestConfiguration {<br />@Autowired<br />private RestTemplateBuilder builder;<br />CBean<br />public RestTemplate restTemplate(){<br />return builder.build();<br />}<br />}
2.QuartzConfiguration
QuartzConfiguration类用于定时任务。
import org.quartz.JobBuilder;<br />import org.quartz.JobDetail;<br />import org.quartz.SimpleScheduleBuilder;<br />import org.quartz.Trigger;<br />import org.quartz.TriggerBuilder;<br />import org.springframework.context.annotation.Bean;<br />import org.springframework.context.annotation.Configuration;<br />import com.waylau.spring.cloud.weather.job.WeatherDataSyncJob;<br />/*★<br />*Quartz配置类.<br />*<br />*since 1.0.0 2017年10月23日<br />* author Way Lau<br />*/<br />@configuration<br />public class QuartzConfiguration <br />private final int TIME=1800;1/更新频率<br />@Bean<br />public JobDetail weatherDataSyncJobJobDetail(){<br />return JobBuilder.newJob(WeatherDataSyncJob.class).withIdentity<br />("weatherDataSyncJob")<br />.storeDurably() .build(;<br />}<br />CBean<br />public Trigger sampleJobTrigger({<br />SimpleScheduleBuilder scheduleBuilder = SimpleScheduleBuilder.<br />simpleschedule()<br />.withIntervalInSeconds (TIME).repeatForever();<br />return TriggerBuilder.newTrigger().forJob(weatherDataSyncJob-<br />JobDetail())<br />.withIdentity("weatherDataSyncTrigger").withSchedule<br />(scheduleBuilder).build();<br />}<br />}
值对象
值对象我们只需要保留City即可,其他值对象都可以删除了。需要注意的是,由于天气数据采集微服务并未涉及对XML数据的解析,所以之前在City上添加的相关的JABX注解,都是可以一并删除的。
以下是新的City类。
public class City {<br />private String cityId;<br />private string cityName;<br />private string cityCode;<br />private String province;<br />1/省略getter/setter方法}
工具类
工具类XmlBuilder的代码都可以删除了。
清理前端代码、配置及测试用例
已经删除的服务接口的相关测试用例自然也是要一并删除的。
同时,之前所编写的页面HTML、JS文件也要一并删除。
最后,要清理Thymeleaf在 application.properties文件中的配置,以及build.gradle文件中的依赖。
测试和运行
首先,在进行测试前,需要将Redis服务器启动起来。
而后再启动应用。启动应用之后,定时器就自动开始执行。整个同步过程可以通过以下控制台信息看到。
2017-10-29 22:26:41.748 INFO 13956---[eduler_Worker-1] c.w.s.c.weather.<br />job.WeatherDatasyncJob<br />:Start天气数据同步任务<br />2017-10-29 22:26:41.749 INFO 13956---[eduler_Worker-1] c.w.s.c.weather.<br />job.weatherDataSyncJob:天气数据同步任务中,cityId:101280601<br />2017-10-29 22:26:41.749 INFO 13956---[eduler_Worker-1] s.c.w.s.Weather<br />DataCollectionServiceImpl: Start同步天气.cityId:101280601<br />2017-10-29 22:26:41.836 INFO 13956 ---[<br />main]o.s.b.w.embedded.<br />tomcat.TomcatwebServer: Tomcat started on port(s):8080 (http)<br />2017-10-29 22:26:41.840 INFO 13956 ---[<br />main]c.w.spring.<br />cloud.weather.Application:Started Application in 4.447 seconds<br />(JVM running for 4.788)<br />2017-10-29 22:26:41.919 INFO 13956---[eduler_Worker-1] S.c.w.s.eather<br />DatacollectionServiceImpl :End同步天气<br />2017-10-29 22:26:41.920 INFO 13956---[eduler Worker-1] C.W.s.c.weather.<br />job.WeatherDataSyncJob:End 天气数据同步任务
由于我们只是在代码里面“硬编码”了一个城市ID为“101280601”的城市信息,所以,只有一条同步记录。
当然,我们也能通过Redis Desktop Manager,来方便查看存储到Redis里面的数据,如图7-3所示。
本篇内容给大家讲解的是天气数据采集微服务的实现
下篇文章给大家讲解天气数据API微服务的实现;
觉得文章不错的朋友可以转发此文关注小编;
感谢大家的支持!!
本文就是愿天堂没有BUG给大家分享的内容,大家有收获的话可以分享下,想学习更多的话可以到微信公众号里找我,我等你哦。