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

2019 年 10 月 25 日

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

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


  • 场景需求 1:根据当地历年的天气信息,预测明年大致的高温到来的时间

  • 场景需求 2:近来天气多变,如果明天下雨,能否在早上上班前,给我一个带伞提醒通知

  • 场景需求 3:领导发话“最近经济不景气,公司财务紧张,那个服务器,你们提供天气、路况等服务的那几个小程序一起用吧,但要保证正常提供服务”。


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


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


场景需求


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


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


  • 根据城市、日期查询(支持未来 3 天)国内城市天气信息

  • 不限制查询次数,支持较大并发查询(1000)


2. 天气提醒


  • 订阅国内城市天气信息,根据实际订阅城市区域,提醒明天下雨带伞

  • 使用钉钉进行通知


整体架构


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



  • 通过 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 即可:



获取 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/v1alpha1kind: Servicemetadata:  name: weather-store  namespace: defaultspec:  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/v1alpha1kind: CronJobSourcemetadata:  name: weather-cronjobspec:  schedule: "0 */3 * * *"  data: '{"message": "sync"}'  sink:    apiVersion: serving.knative.dev/v1alpha1    kind: Service    name: weather-store
复制代码


执行命令:


kubectl apply -f WeatherCronJob.yaml
复制代码


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



提供天气预报查询 RESTful API


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


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


apiVersion: serving.knative.dev/v1alpha1kind: Servicemetadata:  name: weather-service  namespace: defaultspec:  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:城市区域代码。如北京市区域代码:110000date:查询日期。如格式: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)


2019 年 10 月 25 日 17:471009

评论

发布
暂无评论
发现更多内容

DolphinDB与MongoDB在时序数据上的对比测试

DolphinDB

mongodb 分布式系统 时序数据库 DolphinDB 数据库开发

DeFi(去)中心化DAPP系统软件开发

开發I852946OIIO

系统开发

盘点2020 | 疫情下的思考和学习

soolaugust

盘点2020

答了Mybatis这个问题后,面试官叫我回去等通知……

田维常

mybatis

dubbogo 3.0:牵手 gRPC 走向云原生时代

阿里巴巴云原生

go gRPC 云原生 中间件 dubbo-go

IDEA 文档插件 DocView 版本更新:修改 UI 并支持 IDEA 2020.3 !

程序员小航

idea插件 IntelliJ IDEA 文档生成

量化交易APP系统软件开发(现成)

开發I852946OIIO

系统开发

架构师训练营W09作业

Geek_f06ede

Canvas入门实战之用javascript面向对象实现一个图形验证码

徐小夕

Java 前端 canvas

硬核编程:30天=一个网站+一份周刊

老魚

程序员 建站 web全栈

盘点2020 | 30岁了,我终于入门编程了

希望

盘点2020

码了2000多行代码就是为了讲清楚TLS握手流程(续)

新世界杂货铺

golang https

在线医疗的发展和优势

anyRTC开发者

android 音视频 WebRTC RTC 医疗方案

如何快速打造一款钉钉 Go sdk

Ceelog

go golang 钉钉 企业微信

【经验分享】RTC技术系列之音频编解码

邵帅

《大数据算法》.pdf

田维常

算法

SPI 在 Dubbo中 的应用

vivo互联网技术

Java jdk dubbo spi

LeetCode题解:127. 单词接龙,BFS+统计单词变化次数,JavaScript,详细注释

Lee Chen

算法 LeetCode 前端进阶训练营

腾讯高工强烈推荐的“Netty速成手册”原理+应用+调优,带你将知识点一网打尽

比伯

Java 编程 程序员 架构 Netty

智慧警务可视化平台开发,重点人员管控系统搭建

t13823115967

智慧公安 智慧警务系统开发

anyRTC实时音视频-社交娱乐解决方案

anyRTC开发者

ios android 音视频 WebRTC RTC

Prometheus TSDB(Part 2):预写日志(WAL)和检查点

_why先生

云原生 Prometheus tsdb 可观察性

硬肝到秃头!Alibaba强推并发编程笔记我跪了,真的学到好多东西!

Java架构追梦

Java 学习 架构 面试 并发编程

通过Postman和coding.net发布API

太极程序员

Postman API

智慧社区系统开发方案,智慧平安小区综合管理系统建设

WX13823153201

智慧社区系统开发

EZYTRX波场智能合约APP系统软件开发

开發I852946OIIO

系统开发

智慧城市建设,社区智能化系统搭建解决方案

t13823115967

智慧城市 平安小区

产品策略闭环是个什么环?

万事ONES

项目管理 团队协作 需求管理 需求分析 产品策略

【小菜学网络】数据链路层概述

fasionchan

网络编程 计算机网络 网络协议 TCP/IP

一文带你彻底了解大数据处理引擎Flink内存管理

华为云开发者社区

大数据 数据 处理

从 JMM 透析 volatile 与 synchronized 原理

码哥字节

volatile JVM JMM Java 25 周年 synchronized

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