35

基于 Knative Serverless 技术实现天气服务(上篇)

 4 years ago
source link: https://www.tuicool.com/articles/uUnQRzJ
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

提到天气预报服务,我们第一反应是很简单的一个服务,目前网上有大把的天气预报 API 可以直接使用,有必要去使用 Knative 搞一套吗?杀鸡用牛刀?先不要着急,我们先看一下实际的几个场景需求:

  • 场景需求 1:根据当地历年的天气信息,预测明年大致的高温到来的时间
  • 场景需求 2:近来天气多变,如果明天下雨,能否在早上上班前,给我一个带伞提醒通知
  • 场景需求 3:领导发话“最近经济不景气,公司财务紧张,那个服务器,你们提供天气、路况等服务的那几个小程序一起用吧,但要保证正常提供服务”。

从上面的需求,我们其实发现,要做好一个天气预报的服务,也面临内忧(资源紧缺)外患(需求增加),并不是那么简单的。不过现在更不要着急,我们可以使用 Knative 帮你解决上面的问题。

关键词:天气查询、表格存储,通道服务,事件通知

场景需求

首先我们来描述一下我们要做的天气服务场景需求:

1. 提供对外的天气预报 RESTful API

  • 根据城市、日期查询(支持未来 3 天)国内城市天气信息
  • 不限制查询次数,支持较大并发查询(1000)

2. 天气提醒

  • 订阅国内城市天气信息,根据实际订阅城市区域,提醒明天下雨带伞
  • 使用钉钉进行通知

整体架构

有了需求,那我们就开始如何基于 Knative 实现天气服务。我们先看一下整体架构:

NJvyyqr.png!web

  • 通过 CronJob 事件源,每隔 3 个小时定时发送定时事件,将国内城市未来 3 天的天气信息,存储更新到表格存储
  • 提供 RESTful API 查询天气信息
  • 通过表格存储提供的通道服务,实现 TableStore 事件源
  • 通过 Borker/Trigger 事件驱动模型,订阅目标城市天气信息
  • 根据订阅收到的天气信息进行钉钉消息通知。如明天下雨,提示带伞等

基于内容较多,我们分上、下两篇分别进行介绍:

  • 上篇我们会主要介绍如何对接第三方的天气预报 API、定时同步并更新天气信息以及提供 RESTful API;
  • 下篇我们会主要介绍如何实现 TableStore 事件源、订阅天气信息并通过钉钉发送提醒通知;

基于 Knative 实现天气服务 - 上篇

对接高德开放平台天气预报 API

查询天气的 API 有很多,这里我们选择高德开放平台提供的天气查询 API,使用简单、服务稳定,并且该天气预报 API 每天提供 100000 免费的调用量,支持国内 3500 多个区域的天气信息查询。另外高德开放平台,除了天气预报,还可以提供 IP 定位、搜索服务、路径规划等,感兴趣的也可以研究一下玩法。

登录高德开放平台: https://lbs.amap.com , 创建应用,获取 Key 即可:

baeUR3u.png!web

获取 Key 之后,可以直接通过 url 访问: https://restapi.amap.com/v3/weather/weatherInfo?city=110101&extensions=all&key= < 用户 key>,返回天气信息数据如下:

复制代码

{
"status":"1",
"count":"1",
"info":"OK",
"infocode":"10000",
"forecasts":[
{
"city":" 杭州市 ",
"adcode":"330100",
"province":" 浙江 ",
"reporttime":"2019-09-24 20:49:27",
"casts":[
{
"date":"2019-09-24",
"week":"2",
"dayweather":" 晴 ",
"nightweather":" 多云 ",
"daytemp":"29",
"nighttemp":"17",
"daywind":" 无风向 ",
"nightwind":" 无风向 ",
"daypower":"≤3",
"nightpower":"≤3"
},
...
]
}
]
}

定时同步并更新天气信息

同步并更新天气信息

该功能主要实现对接高德开放平台天气预报 API, 获取天气预报信息,同时对接阿里云表格存储服务(TableStore),用于天气预报数据存储。具体操作如下:

  • 接收 CloudEvent 定时事件
  • 查询各个区域天气信息
  • 将天气信息存储或者更新到表格存储

在 Knative 中,我们可以直接创建服务如下:

复制代码

apiVersion:serving.knative.dev/v1alpha1
kind:Service
metadata:
name:weather-store
namespace:default
spec:
template:
metadata:
labels:
app:weather-store
annotations:
autoscaling.knative.dev/maxScale:"20"
autoscaling.knative.dev/target:"100"
spec:
containers:
- image:registry.cn-hangzhou.aliyuncs.com/knative-sample/weather-store:1.2
ports:
- name:http1
containerPort:8080
env:
- name:OTS_TEST_ENDPOINT
value:http://xxx.cn-hangzhou.ots.aliyuncs.com
- name:TABLE_NAME
value:weather
- name:OTS_TEST_INSTANCENAME
value:${xxx}
- name:OTS_TEST_KEYID
value:${yyy}
- name:OTS_TEST_SECRET
value:${Pxxx}
- name:WEATHER_API_KEY
value:xxx

关于服务具体实现参见 GitHub 源代码: https://github.com/knative-sample/weather-store

创建定时事件

这里或许有疑问:为什么不在服务中直接进行定时轮询,非要通过 Knative Eventing 搞一个定时事件触发执行调用?那我们要说明一下,Serverless 时代下就该这样玩 - 按需使用。千万不要在服务中按照传统的方式空跑这些定时任务,亲,这是在持续浪费计算资源。

言归正传,下面我们使用 Knative Eventing 自带的定时任务数据源(CronJobSource),触发定时同步事件。

创建 CronJobSource 资源,实现每 3 个小时定时触发同步天气服务(weather-store),WeatherCronJob.yaml 如下:

复制代码

apiVersion: sources.eventing.knative.dev/v1alpha1
kind: CronJobSource
metadata:
name: weather-cronjob
spec:
schedule:"0 */3 * * *"
data:'{"message": "sync"}'
sink:
apiVersion: serving.knative.dev/v1alpha1
kind: Service
name: weather-store

执行命令:

复制代码

kubectl apply -fWeatherCronJob.yaml

现在我们登录阿里云表格存储服务,可以看到天气预报数据已经按照城市、日期的格式同步进来了。

7nqa2mq.png!web

提供天气预报查询 RESTful API

有了这些天气数据,可以随心所欲的提供属于我们自己的天气预报服务了(感觉像是承包了一块地,我们来当地主),这里没什么难点,从表格存储中查询对应的天气数据,按照返回的数据格式进行封装即可。

在 Knative 中,我们可以部署 RESTful API 服务如下:

复制代码

apiVersion:serving.knative.dev/v1alpha1
kind:Service
metadata:
name:weather-service
namespace:default
spec:
template:
metadata:
labels:
app:weather-service
annotations:
autoscaling.knative.dev/maxScale:"20"
autoscaling.knative.dev/target:"100"
spec:
containers:
- image:registry.cn-hangzhou.aliyuncs.com/knative-sample/weather-service:1.1
ports:
- name:http1
containerPort:8080
env:
- name:OTS_TEST_ENDPOINT
value:http://xxx.cn-hangzhou.ots.aliyuncs.com
- name:TABLE_NAME
value:weather
- name:OTS_TEST_INSTANCENAME
value:${xxx}
- name:OTS_TEST_KEYID
value:${yyy}
- name:OTS_TEST_SECRET
value:${Pxxx}

具体实现源代码 GitHub 地址: https://github.com/knative-sample/weather-service

查询天气 RESTful API:

  • 请求 URL

    GET /api/weather/query

复制代码

参数:
cityCode:城市区域代码。如北京市区域代码:110000
date:查询日期。如格式:2019-09-26
  • 返回结果

复制代码

{
"code":200,
"message":"",
"data":{
"adcode":"110000",
"city":" 北京市 ",
"date":"2019-09-26",
"daypower":"≤3",
"daytemp":"30",
"dayweather":" 晴 ",
"daywind":" 东南 ",
"nightpower":"≤3",
"nighttemp":"15",
"nightweather":" 晴 ",
"nightwind":" 东南 ",
"province":" 北京 ",
"reporttime":"2019-09-25 14:50:46",
"week":"4"
}
}

查询:杭州,2019-09-26 天气预报信息示例

测试地址

另外,城市区域代码表可以在上面提供的源代码 GitHub 中可以查看,也可以到高德开放平台中下载: https://lbs.amap.com/api/webservice/download

小结

通过上面的介绍,大家对如何通过 Knative 提供天气预报实现应该有了更多的体感,其实类似的场景我们有理由相信通过 Knative Serverless 可以帮你做到资源利用游刃有余。下一篇会继续我们要实现的内容:通过 Knative 事件驱动,订阅天气信息,钉钉推送通知提醒,欢迎持续关注。

本文转载自阿里巴巴云原生微信公众号(ID:Alicloudnative)


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK