基于阿里云IoT平台的物联网解决方案

去年差不多也是这个时候,我写过一篇《阿里云IoT应用案例》,重点提到了我们对于阿里云IoT SDK的封装并实现自主注册、消息队列规则转发、双向通讯、远程升级和远程控制等功能的设计思路。

又经过一年的持续优化、打磨,我们也落地了一整套物联网解决方案,包括物联网中间件和物联网平台,实现从仪器研发人员快速接入,到运维人员扫码装机注册,到仪器自动数据回传,到运维人员远程升级,再到管理人员物联网卡充值续费,最后到面向经营决策人员的大数据分析应用,拉通了整个业务闭环。

1. 背景

再一次提到背景,在上一篇文章中,简单概述了我们的物联网项目背景和需求,是为了解决在不同操作系统、不同开发语言的仪器,不同通讯协议、不同运营商的平台服务的环境下做一站式解决方案。但这只是技术背景和技术需求,放大来说,促使我们做这件事的原因还是产业数字化升级转型的趋势。一方面通过物联网和大数据等新技术对现有产品的升级、改造、赋能,让机器活起来,让数据流动起来,起到降本增效,辅助决策的作用,这是短期价值;另一方面,通过新技术的结合,面向新的场景探索,完成产品和业务的重塑,实现业务模式的转型,这是长期价值。

引用三个大佬的话来说这件事:

阅读更多

Teambition网盘内测试用评测

最近阿里云盘和Teambition网盘同时出现在市面上,两款产品都来自阿里云智能事业群,据说定位略有不同。其中阿里云盘侧重个人应用,偏生活娱乐,如相册功能,类似百度网盘。而Teambition网盘定位办公协同,类似OneDrive。两套产品都基于阿里云OSS,目前都处于测试阶段。

差不多在今年9月左右,就在Teambition官网看到Wiki和网盘出现在导航页,并标记了Beta。直到11月,有幸在阿里云MVP群拿到Teambition网盘内测资格,才一睹真容。

首先当然是“至尊身份象征”,一封内测邀请邮件外加金闪闪徽章。这个徽章为什么不做在产品里呢?

目前Teambition网盘提供网页端和移动端,先看网页版,可以进入Teambition官网或者通过 pan.aliyun.com 跳转到Teambition网盘。

阅读更多

阿里云云效2020踩坑指南

自2019年加入一家传统生物医疗器械公司以来,我们组建了一支40余人的团队主攻企业数字化转型,做新产品和新业务模式探索。一年多的时间,我们也搭建了一整套基于阿里云的微服务架构的平台体系,包括K8S服务编排、监控预警日志、基于Gitlab和Jenkins的CI/CD等等。此外还使用过Leangoo、Jira、Confluence、企业微信在线文档、NextCloud等协同工具,最后稳定在Jira+Confluence+Nextcloud组合。但由于各个系统不方便打通伴随人员增加,管理压力和安全隐患等问题逐渐暴露出来,所以近期就在考虑用全家桶方案整合各个系统。

我们先后也看了不少方案,像Worktile、Teambition、Jira等。早在18年,我也看过阿里云云效平台,那时候的版本功能和UI还比较简陋,尤其是项目协同这块“很不好用”。而Jira太重,不符合国内用户的使用习惯。最后还是在今年的云栖大会上,重新认识了Teambition。新的UI设计、流水线的引入、知识库WIKI的整合等等,至知识库还支持Markdown、Roadmap、思维导图,而且是在线协同。本来已经选定Teambition了,无意间又在阿里云云效看到新出了云效的2020版,简单浏览过,发现就是Teambition的整合版,与阿里云做了打通,加入了代码仓和成品仓(正因为如此,云效2020的费用比Teambition企业版要贵近200/人年)。此外,还推出了云鹰计划,99人的团队只需1万多就可以用一年。所以我们决定通过云鹰计划试水,毕竟跟我们正在用的阿里云有很好的结合。

任何迁移,任何第一个吃螃蟹的都要付出代价。虽然阿里云效2020确实提供了一些很好用的功能,帮我们解决了一些问题,但还是存在一些“缺陷”,或者是我们使用方法不对又或者是使用习惯问题。我们把这些坑暴露出来,也是希望给到“后人”一些参考,也希望能给到阿里云一些有价值的建议。

1. 项目协作 Projects

  • 任务类型切换不方便

    任务类型的切换要下拉选择,用户需要两步操作,感觉繁琐。而Jira则是需求和任务显示在一个维度里。个人感觉Tag或者Tap的切换操作更好。

  • 添加任务时不能直接添加子任务

    要等主任务添加完成才可以点击添加子任务,不是很方便。

  • 给任务添加工时字段

    任务模板默认没有“工时”字段,而在Scrum中通常需要这个字段作为评估工作量的指标。云效2020(Teambition)是支持自定义任务字段的,进入某个项目,在右上角的“菜单” - 项目设置 - 任务设置 - 任务类型设置 - 选择具体的类别 - 进入字段设置 - 增加“工时”字段。也可以在系统设置中设置,全局项目生效。

阅读更多

阿里云IoT应用案例

最近半年一直在尝试物联网相关技术在传统行业的应用,推动企业数字化转型。结合阿里云和阿里云IoT平台,初步实现了几个主要业务功能,整理分享如下:

1. 背景

核心诉求是终端设备接入物联网:一方面是为了数据的远程交互,另一方面是数据的收集和应用

目前终端种类繁多,未统一平台和标准,操作系统覆盖Windows、Android、Linux. 而IoT模组又依据主流通讯技术分成2G、3G、4G和NB-IoT,不同通讯技术的模组使用的协议不尽相同,这对于终端仪器开发的同学来说是个痛点,各个操作系统和开发语言均需对接IoT模组,一旦模组被更换,又需要重新匹配新的协议。

数据接收端也不好过,不同的运营商有自己的IoT平台,管理物联网卡和数据收发。更有运营商强制要求指定型号的模组只能用自家平台进行数据管理(如移远 BC95-5 只能使用电信Easy IoT平台)。应用系统开发需要维护多个运营商IoT平台,接口亦需开发多套。

阅读更多

《阿里巴巴中台战略思想与架构实践》笔记

1. 共享服务体系搭建

  • ESB解决异构系统之间的交互
  • 去中心化分布式服务框架除了对于 SOA 特性的实现和满足外,相比中心化服务架构最重要的不同就是服务提供者和服务调用者之间在进行服务交互时无需通过任何 服务路由中介, 避免因为中心点带来平台能力难扩展问题,以及潜在的雪崩影响
  • 关于雪崩
    • 企业服务总线架构一旦遇到上面所提到的“雪崩”事故后,故障恢复的时间和成本都非常高昂。因为传统的一台一台重启服务器已经不能进行故障的恢复,因为一旦服务启动起来,前端的访问洪流会立即再次压垮启动后的服务器,唯一正确的方式则是首先切断前端应用对企业服务总线的服务请求,让这10台服务器全部启动后,再开放服务请求,这样才能恢复系统的运行。但因为着急恢复系统,没有来得及定位之前造成开始服务实例出问题的根本原因,这样的系统恢复运行其实处于一个“脆弱”的状态,之前造成服务实例宕机的问题可能让“雪崩”事故再次上演。
  • 微服务架构的典型特征
    • 分布式组成的系统
    • 按照业务划分也不是按照技术划分
    • 做有生命的产品而不是项目
    • 智能化服务端点与傻瓜式服务编排
    • 自动化运维
    • 系统容错
    • 服务快速演化
  • 关于微服务的”微”
    • “微服务”中的这个“微”字给很多人带来了很多误解。从字面意思上,“微”会让人联想到一个微服务就应该是功能足够单一,甚至出现一个服务的实现可能只需要几十或者上百行代码的说法,这应该是最误导人的观点。从技术角度出发,确实可以通过简短的代码实现功能单一的服务,但从一个整体架构考虑,如果是以这样的方式实现各个微服务,则在整个服务体系范畴当中包含太多功能边界,那么对于服务运营的分工和边界就很难界定,给服务接下来的持续运营和维护带来困扰;另外拆分过于细化的服务,势必将带来大量无谓的分布式事务调用,给业务的实现带来额外的工作量和风险。

2. 服务中心建设

  • 服务中心一定是不断发展的
  • 尝试服务化 - 全面服务化 - 服务平台化
  • 服务中心的多样性
    • 接口:API
    • 工具:配置服务、管理服务
    • 数据:大数据分析
  • 服务中心可以进一步划分
  • 服务中心和业务不一定一一对应
  • 服务中心划分原则
    • 三个方面
      • 设计
      • 运营
      • 工程
    • 四个原则
      • 高内聚低耦合
      • 数据完整性
      • 业务可运营
      • 持续渐进

3. 数据拆分

阅读更多

阿里云Kubernetes实战3--DevOps

前言:

在上一篇文章中,我们已经在K8S集群部署了Jenkins、Harbor和EFK。作为本系列最后一篇文章,将通过实际案例串联所有的基础软件服务,基于K8S做DevOps。

整体的业务流程如下图所示:

1

一、一机多Jenkins Slave

阅读更多

阿里云Kubernetes实战2--搭建基础服务

前言:

在系列的第一篇文章中,我已经介绍过如何在阿里云基于kubeasz搭建K8S集群,通过在K8S上部署gitlab并暴露至集群外来演示服务部署与发现的流程。文章写于4月,忙碌了小半年后,我才有时间把后续部分补齐。系列会分为三篇,本篇将继续部署基础设施,如jenkins、harbor、efk等,以便为第三篇项目实战做好准备。

需要说明的是,阿里云迭代的实在是太快了,2018年4月的时候,由于SLB不支持HTTP跳转HTTPS,迫不得已使用了Ingress-Nginx来做跳转控制。但在4月底的时候,SLB已经在部分地区如华北、国外节点支持HTTP跳转HTTPS。到了5月更是全节点支持。这样以来,又简化了Ingress-Nginx的配置。

1

一、Jenkins

阅读更多

阿里云Kubernetes实战1--集群搭建与服务暴露

前言:

考虑到公司持续集成与docker容器技术实施已有一段时间,取得了不错的效果,但对于设备运维、系统隔离、设备利用率和扩展性还有待提升,综合目前比较成熟的微服务技术,打算把现有业务迁移到K8S集群。

由于公司所有业务均部署在阿里云上,最开始就调研了阿里云自己提供的Kubernetes集群,但后来还是放弃了,主要考虑几方面:

  • 阿里云K8S集群尚不成熟,使用的版本也相对较老,不能及时更新版本
  • 阿里云K8S集群目前只支持多主多从结构,同时限定Master节点只能是3个,不能增减,这对于小型业务或者巨型业务均不适用
  • 自建原生K8S集群更有利于拓展和理解整体结构

接下来会详细介绍在阿里云搭建原生Kubernetes集群的过程。

阅读更多

用Docker搭建企业私有云盘NextCloud

前言

本文涉及的操作系统、软件平台和其他环境如下:

  • 云盘服务器
    • CentOS 7
    • WD红盘/阵列盒(可选)
    • 所在网络需要有公网IP
    • Docker CE
    • Docker Compose
    • Nginx with SSL
  • 阿里云
    • DNS
    • CA证书

一、安装Docker

1.1 关闭selinux

阅读更多

利用nodejs在webpack打包完成后自动上传文件到阿里云OSS

项目使用Webpack打包,打包完成后生成一些asset,不管是本地开发还是jenkins持续集成,都希望自动上传这些asset到阿里云OSS,于是用nodejs写一个脚本:

1. upload_oss.js

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
var co = require('co'); 
var OSS = require('ali-oss') //阿里云oss模块
var fs = require("fs"); //文件模块
var path = require("path");

//---------------------------使用说明----------------------------
//获取命令行传入参数(第0个参数是node 第1个参数是js文件 第2个文件是本地文件夹路径 第3个是oss相对目录)
//命令格式举例: node oss/upload_oss.js ../../static/ /static/

var localPath = process.argv[2]
var remotePath = process.argv[3]
if(localPath == null || remotePath == null){
throw new Error("缺少目录参数!");
return
}

localPath = path.resolve(localPath); //本地目录
remotePath = path.resolve(remotePath); //OSS相对目录

if(!fs.existsSync(localPath)){
throw new Error("本地目录"+ localPath + "不存在!")
return
}


//上传列表
var fileDic = new Array();

//阿里云OSS配置
var client = new OSS({
region: 'oss-cn-shenzhen',
accessKeyId: 'xxxx',
accessKeySecret: 'xxxx',
bucket: 'xxxx'
});



console.log('---------上传OSS---------');
console.log('【Step1】 分析目录');

readDir(localPath)

function readDir(filePath){
filePath = path.resolve(filePath);
//遍历文件目录
var pa = fs.readdirSync(filePath);
pa.forEach(function(filename,index){
var file = path.join(filePath,filename)
var info = fs.statSync(file)
//目录
if(info.isDirectory()){
readDir(file);
}
//文件
else {
//添加到上传列表
var localDir = path.join(filePath,filename);
var remoteDir = path.join(remotePath, localDir.replace(localPath,""));
fileDic[localDir] = remoteDir;
console.log("add file:" + localDir)
}
})
}

console.log('【Step2】 上传文件');

co(function* () {
for(var localDir in fileDic)
{
var result = yield client.put(fileDic[localDir], localDir);
console.log("upload from '" + localDir + "' to '" + fileDic[localDir] + "'");
}
console.log('【Step3】 完成');
}
).catch(function (err) {
throw new Error(err);
}
);

2. package.json调用

1
2
3
4
5
"scripts": {
"dev": "webpack-dev-server --devtool inline-source-map --progress --color --watch-poll",
"test": "export NODE_ENV=test && webpack --progress --color && node oss/upload_oss.js ../test_static/ /demo/test_static/",
"prod": "export NODE_ENV=production && webpack --progress --color && node oss/upload_oss.js ../static/ /demo/static/",
}
阅读更多