人过35,被年轻人卷走了一大半,还停留在这个行业的,不是在创业,就是在创业的路上。

创业很难,刚开始没钱没人,啥都要自己干,一个字累。好处是地基是自己搭的,心里有底。不过博主最近健忘的毛病愈发严重了,趁还清醒纪录点滴。

PaaS

博主做的是物联网项目,目前涉及到的通信协议有lora4G/Cat1BLE,传输协议有MQTTHTTPTCP私有协议。大致草图如下:



一般来说,MQTT能满足大部分业务需求,但在某些场景比如文件下发/自定义分包拼包时处理起来比较复杂,这时使用HTTP更合适,但对于设备并不友好(MQTT与HTTP谁最适合物联网?),所以有时自定义协议也不可避免。另外如果觉得MQTT实现或对接起来太麻烦,很多特性又用不到,那其它协议或自定义协议是更好的选择。

MQTT虽然通用,但不是万能的,不是非它不可的,说到底,它也只是一套诞生于具体场景,为了解决某些问题,一步步发展起来的协议罢了。

系统拓扑

然后买服务器,走阿里云,买多少呢?主要是ECS,有以下几点要求:

  1. 前台、后台、PaaS网关分开部署;
  2. 还有各类中间件,前期就把它们一块放一台机子上得了;
  3. 一个私有docker镜像仓库用于CI/CD,与业务无关,独立部署,带宽也独立(上行为主,几乎不下行,所以开个最小1M带宽即可)。

这么看来至少5台ECS,网络架构如下:



麻雀虽小,五脏俱全。横向和纵向都有较好划分,界限清晰,方便以后扩展。

考虑到便于运维/CI/CD/微服务/日后引入K8S,所有服务都以docker容器形式部署。

为了省钱&安全计,只给必要的两台ECS开了公网(EIP),除docker镜像仓库外,挂载nginx的那台也要开通公网对外提供服务,对内转发请求。需要注意的是,ECS若没有公网IP,则自身也无法访问外网(记得以前可不是这样的)。那如果内网ECS要调用外部第三方接口怎么办呢?同样可经由nginx转发。在此场景下,nginx兼具反向和正向代理的职责。

内网ECS获取公网docker镜像也存在无法拉取的问题,可以在私有仓库的那台机子上先拉取下来,然后打个tag,再push到本地仓库,如此其它ECS就能在私有仓库里pull到该镜像了。示例如下:

# 私有仓库基于registry,端口6500

# 以nacos为例,在部署了仓库的ECS上执行
docker pull nacos/nacos-server
docker tag nacos/nacos-server:latest localhost:6500/nacos-server
# 重新发布到私有仓库
docker push localhost:6500/nacos-server # 内网ECS拉取镜像
docker pull 仓库ECS内网地址:6500/nacos-server

阿里云ecs.s6-c1m2.xlarge 4M带宽(固定)比ecs.t5-lc1m4.large (无性能约束实例) 5M带宽 (固定)下行速率更快更稳定,后者卡的一笔,经常断连(可能受其它共享主机影响?),直接升级到15M后可正常使用。

反向代理,除了nginx,我们还使用了HAProxy。前者处理http转发(L7),后者处理tcp转发(L4)。虽然nginx从1.9.0版本开始,新增了ngx_stream_core_module模块,使nginx支持四层负载均衡。然而其默认编译的时候该模块并未编译进去,需要编译的时候添加--with-stream,使其支持stream代理。目前官方也没有提供默认有该功能的docker镜像,需要自己打包,稍显麻烦。

自动发布

自动发布是CI/CD的基础。本人使用的是gitlab-ci,相比jenkins,gitlab-ci资料并不多,不过其官方文档已经挺全面了,遇到问题基本上也有前人踩过坑,可参看博主以前写的一篇随笔GitLab-CI/CD入门实操

以后端应用为例,流程大致如下:



有几点图中未表明:

  • 代码提交/merge到不同分支,将触发各自分支的发布流程。比如dev分支将发布到内网测试环境,master分支将发布到线上生产环境。
  • 对于前面说的生产服务器没有公网地址的情况,公司内网的gitlab-runner无法直接登录,就需要拥有公网地址的服务器作为跳板机登录。

如果在发布流程中加入代码规范check、code review、通知机制、及手动干预功能(如提供管理界面,测试人员点击测试通过或不通过按钮控制流程走向)等,那CI/CD就初具雏形了。

git分支管理

顺便再说说代码分支。一直都存在的有master和dev分支。master对应线上生产版本代码,dev对应本地开发版本代码。生产部署都走master分支,当线上有bug或紧急需求时,从master分支切一个hotfix分支出来,开发测试完毕之后并回master并删除该hotfix分支。而产品迭代需要处理的bug和需求,从dev切分支,一次迭代一般起一个feature分支,开发测试完毕后并回dev分支(或并回后做测试,视情况而定),然后dev再merge到master,上线。流程大致如下:



注意hotfix和feature分支可能同时会有多个,完成之后即删除。

其它资料

为什么用MQTT而不用TCP长连接透传

互联网推送服务原理:长连接+心跳机制(MQTT协议)

LoRaWAN介绍 - LoRa从业者读这篇就够了

基于GitLab的工作流程设计

<5人公司极简研发方案的更多相关文章

  1. 简单物联网:外网访问内网路由器下树莓派Flask服务器

    最近做一个小东西,大概过程就是想在教室,宿舍控制实验室的一些设备. 已经在树莓上搭了一个轻量的flask服务器,在实验室的路由器下,任何设备都是可以访问的:但是有一些限制条件,比如我想在宿舍控制我种花 ...

  2. 利用ssh反向代理以及autossh实现从外网连接内网服务器

    前言 最近遇到这样一个问题,我在实验室架设了一台服务器,给师弟或者小伙伴练习Linux用,然后平时在实验室这边直接连接是没有问题的,都是内网嘛.但是回到宿舍问题出来了,使用校园网的童鞋还是能连接上,使 ...

  3. 外网访问内网Docker容器

    外网访问内网Docker容器 本地安装了Docker容器,只能在局域网内访问,怎样从外网也能访问本地Docker容器? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Docker容器 ...

  4. 外网访问内网SpringBoot

    外网访问内网SpringBoot 本地安装了SpringBoot,只能在局域网内访问,怎样从外网也能访问本地SpringBoot? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装Java 1 ...

  5. 外网访问内网Elasticsearch WEB

    外网访问内网Elasticsearch WEB 本地安装了Elasticsearch,只能在局域网内访问其WEB,怎样从外网也能访问本地Elasticsearch? 本文将介绍具体的实现步骤. 1. ...

  6. 怎样从外网访问内网Rails

    外网访问内网Rails 本地安装了Rails,只能在局域网内访问,怎样从外网也能访问本地Rails? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Rails 默认安装的Rails端口 ...

  7. 怎样从外网访问内网Memcached数据库

    外网访问内网Memcached数据库 本地安装了Memcached数据库,只能在局域网内访问,怎样从外网也能访问本地Memcached数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装 ...

  8. 怎样从外网访问内网CouchDB数据库

    外网访问内网CouchDB数据库 本地安装了CouchDB数据库,只能在局域网内访问,怎样从外网也能访问本地CouchDB数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动Cou ...

  9. 怎样从外网访问内网DB2数据库

    外网访问内网DB2数据库 本地安装了DB2数据库,只能在局域网内访问,怎样从外网也能访问本地DB2数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动DB2数据库 默认安装的DB2 ...

  10. 怎样从外网访问内网OpenLDAP数据库

    外网访问内网OpenLDAP数据库 本地安装了OpenLDAP数据库,只能在局域网内访问,怎样从外网也能访问本地OpenLDAP数据库? 本文将介绍具体的实现步骤. 1. 准备工作 1.1 安装并启动 ...

随机推荐

  1. VS·卸载进程卡死"正在配置您的系统,这可能需要一些时间"

    阅文时长 | 0.34分钟 字数统计 | 596.8字符 主要内容 | 1.引言&背景 2.声明与参考资料 『VS·卸载进程卡死"正在配置您的系统,这可能需要一些时间"』 ...

  2. [bug] Docker:Error ruuning deviceCreate(createSnapDevice) dm_task_run failed

    原因 删除容器时报错,元信息出错,需要修复 最后一个参数要改成自己docker元信息路径,如: thin_check --clear-needs-check-flag /var/lib/docker/ ...

  3. SpringBoot 整合 mybatis 开启驼峰命名规则自动转换

    引言 在使用 MyBatis 进行实际项目开发时,如果数据库表字段名与Java 实体类属性名不一致,映射时则需要编写表字段列表与 Java 实体类属性的映射关系,即resultMap,如下: < ...

  4. 思考一个问题STM32的

    如果一个定时中断刚刚进入中断服务函数 但是服务函数执行时间太长   又一次触发了中断 会怎样

  5. Springboot2.x入门——helloWorld

    Springboot2.x入门--helloWorld 一.简介 1.1 Springboot简介 Spring Boot是由Pivotal团队提供的全新框架,其设计目的是用来简化新Spring应用的 ...

  6. JMeter36个内置函数及11个新增函数介绍

    JMeter内置了36个函数,这些函数可以通过函数助手进行编辑和测试.了解这些函数,不仅能提高JMeter的使用熟练度,也有助于知晓测试工具或测试框架通用的函数有哪些,在自主设计时,作为参考借鉴. J ...

  7. Django(45)drf序列化类的使用(Serializer)

    前言 上一篇文章我们讲述了序列化,这篇就带大家一起来实现以下序列化 Serializer 我们使用序列化类Serializer,我们来看下源码结构,这里推荐使用pycharm左边导航栏的Structu ...

  8. Nginx 配置实例-配置动静分离

    Nginx 配置实例-配置动静分离 1. 静态资源的创建 2. nginx 动静分离的配置 3. 验证 1. 静态资源的创建 这里使用的静态资源主要为 HTML 静态文件和图片. mkdir -vp ...

  9. GPU上的基本线性代数

    GPU上的基本线性代数 cuBLAS库提供了基本线性代数子例程(BLAS)的GPU加速实现.cuBLAS通过针对NVIDIA GPU进行了高度优化的嵌入式行业标准BLAS API来加速AI和HPC应用 ...

  10. Pandas之:深入理解Pandas的数据结构

    目录 简介 Series 从ndarray创建 从dict创建 从标量创建 Series 和 ndarray Series和dict 矢量化操作和标签对齐 Name属性 DataFrame 从Seri ...