记录第一次带后端团队

news2024/11/20 1:48:32

在过去的一个半月里我第一次作为后端开发组长角色参与公司项目从0到1的开发,记录这一次开发的经历。

1、背景介绍

首先说明一下背景。我所在的公司是做智慧社区相关业务,开发的项目是系统升级工具,方便公司实施同事安装和升级系统。

参与后端开发一共四个人,包括我在内。其他三个同事有一个是应届生、两个做大数据的。按照公司的技术规划,对内项目开发节奏要短平快,用Python语言完成,对外的项目一律用Java语言完成。

项目经过正常开发生命周期,包括需求采集、产品设计、系统设计、详细设计、编码、测试等过程。其中详细设计就是针对接口做的详细设计,一共用时3天完成,设计了45个功能点,包括40个接口和5个初始化准备工作。编码用时计划为3周。最终在时间点之内完成了相关的开发。

我在这次开发过程中担任的是组长的角色,主要的任务包括:

(1)项目框架的搭建。本次开发是一个从0到1的过程,在此之前并没有Python项目的框架。

(2)关键技术的实现。包括通用接口,复杂的技术点。

(3)任务分配。所有接口根据任务量分配给指定的成员,完成最多的接口开发。


2、项目框架搭建

Python做web开发常用的项目框架其实并不是很多,我的候选项有三个:

Django 前后端不分离框架、Flask 最容易上手的框架、FastAPI 异步高性能框架。

对比这三个框架,我从业务逻辑、公司技术栈、复杂度等三个角度出发,选择了Flask。

业务逻辑

业务逻辑对性能并没有特别要求,就是通过接口调用运维的ansible脚本,没有高并发,计算密集等任务,所以三个都能满足。

技术栈

公司技术栈是前后端分离,所以Django这种前后端不分离的框架并不适合,虽然Django也可以做纯后端开发(防杠)。

复杂程度

复杂度来说肯定是Flask最简单。Django号称大而全,配置复杂。FastAPI是异步框架,需要学习异步编程,虽然用来做同步框架也很丝滑,但是学习成本需要增加很多。其他三个同事都没有做过Python项目,所以尽量减少学习成本。

经过这三个方向的衡量,最终确定了Flask框架,搭配peewee orm数据库框架。核心的技术包括:

(1)web框架 Flask

(2)数据库ORM框架 peewee

(3)数据库 sqlite

(4)运维脚本执行模块 subprocess

(5)WSGI服务 Gunicorn

(6)代码检查工具pre-commit

在编码前我已经准备好完整的项目框架,写好了数据库CRUD接口的demo,后续开发过程同事模仿相关接口,一定程度上提高了开发效率。


3、关键技术实现

带团队开发并且是带领成员第一次做Python项目,自然要将有挑战的任务安排给自己。在关键技术的实现上挑选三个有代表性的讲解。三个分别是:系统命令执行通用接口、流式日志、sqlite 多线程写问题解决。

系统命令通用接口

项目主要用于公司开发的其他系统安装和升级,因此需要调用运维人员用ansible编写的相关脚本。调用的ansible脚本格式如下:

ansible-playbook 03.mysql.yml
ansible-playbook 08.zk.yml

需要到指定的路径下执行如上的命令。在详细设计阶段就知道需要使用Python调用系统命令的工具,所以就让应届生同事调研了subprocess模块,输出相关文档。一来是给新人一个学习方向,再则借这个机会熟悉项目需要的技术。

在开发阶段根据对相关模块的理解,完成了通用接口的开发。写通用接口切忌朝令夕改,依赖它的代码也要随之变化。一两次还能接受,次数多估计要被问候祖宗了。所以该接口实现程度不仅仅是写完,而且是自己亲自调用,确认没有问题才宣告完成。

在没有完成之前耐着性子调试,直到没有任何问题才在群里告诉其他开发人员。整个系统中需要大量的调用该命令执行脚本,最终也都比较顺利的完成,没有因为接口造成的bug。

流式日志

按照产品的设计,当一个组件在安装时需要在web页面上展示日志,并且日志的格式要和终端中安装日志一样,也就是一行一行的滚动打印。产品对日志的要求是全量滚动展示,刷新页面要能够再次全量展示出来。为了实现该功能,调研了三个方案:

一、定时刷新。缺点:日志有几万行,每一次读取全部日志给前端,前端会卡顿,而且打印也不连续,体验不好。

二、websocket。可以完成后端向前端的主动推送,但是刷新页面并不会从头开始推送。

三、流式响应。可以将大块文件切分成小块分批传给前端,刷新页面时会再次从头开始推送,符合要求。

经过对比最终使用了流式响应,也就是ChatGPT那种响应的方式。但是需要解决一个问题:什么时候结束推送?因为安装一边向文件中写入日志,流式日志一边读出日志,如果日志已经读完了安装还没结束,那这个时候肯定需要等待而不是停止响应。

解决办法是在安装完成之后插入标记字符,当流式日志读取到标记字符时就表明结束了,没有读取到标记字符则等待。核心代码如下:

def log_flow():
    query = request.values
    log_path = query["log_path"]

    def generate():
        with open(log_path, "r") as f:
            while True:
                chunk = f.read(800)
                if not chunk or chunk.isspace():
                    time.sleep(0.1)
                if chunk == 800 * "-":
                    break
                content = json.dumps({"content": chunk})
                yield f"event: message\ndata: {content}\n\n"
                time.sleep(0.05)

return Flask_response(generate(), mimetype="text/event-stream"

效果:

sqlite3 多线程写问题

在数据库存储这一块,领导钦定用sqlite3,咱也据理力争过用MySQL,but无效。领导说该项目只需要一个轻量的数据库即可,sqlite3轻量,所以就很合适。而且其他项目中已经使用的非常成熟了。好吧,既然领导坚持,我也只能硬着头皮上了。

开始还没问题,到了项目开发中后期就发现问题了,接口经常报错:

File "/home/ljk/.virtualenvs/idt_dev/lib/Python3.8/site-packages/peewee.py", line 3246, in execute_sql
cursor.execute(sql, params or ())
File "/home/ljk/.virtualenvs/idt_dev/lib/Python3.8/site-packages/peewee.py", line 3014, in __exit__
reraise(new_type, new_type(exc_value, *exc_args), traceback)
File "/home/ljk/.virtualenvs/idt_dev/lib/Python3.8/site-packages/peewee.py", line 192, in reraise
raise value.with_traceback(tb)
File "/home/ljk/.virtualenvs/idt_dev/lib/Python3.8/site-packages/peewee.py", line 3246, in execute_sql
cursor.execute(sql, params or ())
peewee.OperationalError: database is locked

查询之后发现是sqlite3不支持多线程写。sqlite3支持事务,是用库锁来完成的。当一个写入开始后,整个数据库都加锁了,再次有写操作就会报错。

这个问题首先从技术上是不好解决的,sqlite3的架构设计就是如此,还能让它支持多线程写吗?只能通过业务逻辑解决。经过一次会议讨论之后,得出几个解决方法:

  • 分库。将写操作分到不同的库里完成。既然写操作会锁库,那就分出不同的库,就能避免锁库的问题。
  • 全局写队列。将所有的写放到一个消息队列里面,将多线程的写变成串行的写。
  • 全局写标识。所有的写操作开始前判断是否有可写标识,能写入就写入,否则接口返回,告诉前端数据库繁忙。

经过投票,大家一致决定用第三种方式实现,技术难度最小,代码侵入性最少。因为第三种方案是我提出来的,所以最终由我来完成。具体的过程可参见另一篇文档《peewee操作sqlite锁表问题分析》。

最终是解决了该问题,虽然不是优雅,但是在目前的时间成本和风险控制上局部是最优解了。后续将调研peewee这个ORM框架提供的sqliteQueueDatabase实现写队列。

摘录于peewee扩展插件playhouse:

SqliteQueueDatabase可作为常规SqliteDatabase。如果你想简单点 read and write 从访问sqlite数据库多线程.

SQLite在任何给定的时间只允许一个连接写入数据库。因此,如果您有一个多线程应用程序(例如Web服务器)需要写入数据库,当一个或多个尝试写入的线程无法获取锁时,您可能会偶尔看到错误。

SqliteQueueDatabase 旨在通过一个长期存在的连接发送所有写查询,从而简化操作。好处是,您可以看到多个线程在向数据库写入时没有冲突或超时。但是,缺点是您不能发出包含多个查询的写事务——本质上,所有写操作都在自动提交模式下运行。


4、个人感受

第一次带团队开发,才明白很多事情。

做项目的主人公

第一真正理解什么叫主人公意识。各种文章都说要对项目有主人公意识才能成长更快。我感觉只有站在这样一个位置上才能感受到这种意识。

项目进度的第一责任人就是你,项目中出现了大大小小的问题都是找你。领导会问题项目进度如何,有没有阻塞,能不能按期完成?队员会问这个校验框架是否ok?这个语法有没有问题?测试会找你说这个bug该给谁的?所以你必须对这个项目了如指掌,小到代码的一个配置项,大到工程进度的把控。开发过程中有任何问题都得及时顶上,组长就是一块砖,哪里需要哪里搬~

团队和谐

再说说团队的和谐。以前做一个小开发,只要完成自己的任务就可以了,团队的氛围影响我写代码的速度吗?带团队开发就不一样。团队中有各种特点的同事,有埋头苦干不汇报进度的、有能力强脾气差的、有脾气好进度慢的。总之各种性格的人都会存在。

本次开发中就遇到了一个能力强脾气差的,看到技术上小问题就直接群里开怼,谁不是热血小青年?第一次遇到这种情况可想而知。领导不得不为此找我们谈话一两次,甚至惊动了大部门领导。那段时间团队氛围特别差,没有人说话。我也不敢多说什么,害怕气氛更差,项目不能如期完成,到那个时候不是我的问题也变成我的问题了。所以只能选择忍一忍,尽量回避分歧。好在领导的谈话起到很大的作用,该安抚的安抚,该批评的批评,后来也没有发生语言的冲突,顺利按期完成项目。


5、总结

第一次带团队做项目对我来说是一次挑战和提高。从技术层面讲让我以后面对技术选型时能以更高的角度看待问题;从个人角度讲这是一次难得的机会让我负责开发团队,对接测试团队、前端团队、运维团队等。这对我的沟通交流都是一次锻炼。

最后,希望下一次做的更好,让所有组员都能有一些进步。

开发工具推荐

JNPF,很多人都用过它,它是功能的集大成者,任何信息化系统都可以基于它开发出来。

原理是将开发过程中某些重复出现的场景、流程,具象化成一个个组件、api、数据库接口,避免了重复造轮子。因而极大的提高了程序员的生产效率。

官网:www.jnpfsoft.com/?csdn,如果你有闲暇时间,可以做个知识拓展。

这是一个基于Java Boot/.Net Core构建的简单、跨平台快速开发框架。前后端封装了上千个常用类,方便扩展;集成了代码生成器,支持前后端业务代码生成,满足快速开发,提升工作效率;框架集成了表单、报表、图表、大屏等各种常用的Demo方便直接使用;后端框架支持Vue2、Vue3。

为了支撑更高技术要求的应用开发,从数据库建模、Web API构建到页面设计,与传统软件开发几乎没有差异,只是通过低代码可视化模式,减少了构建“增删改查”功能的重复劳动

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1000959.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

安全可靠的文件传输服务助力完成更高效的医疗保健工作(下)

医疗保健事业是关乎人类健康和社会发展的重要领域,它需要依赖海量的医疗数据,如病人信息、医疗影像、化验结果、电子病历、诊断建议等。这些数据不仅关系到病人的个人利益和医疗质量,也关系到医院的运行效率和医疗水平。因此,如何…

荣耀崛起礼包码2023,荣耀崛起攻略

荣耀崛起是一款传统的卡牌手游,它将区域探索游戏无缝集成到卡牌游戏中。相信很多玩家都很好奇,荣耀崛起礼包码2023是什么?有没有给新手的一些攻略建议呢?下面小编就和大家简单分享一下,感兴趣的朋友,一起来…

uni-app(微信小程序)图片旋转放缩,文字绘制、海报绘制

总结一下: 要进行海报绘制离不开canvas,我们是先进行图片,文字的拖拽、旋转等操作 最后再对canvas进行绘制,完成海报绘制。 背景区域设置为 position: relative,方便图片在当前区域中拖动等处理。添加图片&#xff0…

一文掌握SSD、EMMC、UFS原理与差异

有一天,小明在他的智能手机上播放了一段高清视频,发现视频播放得非常流畅。他感叹道:“现在的存储技术真是太棒了!”他的朋友小华却告诉他:“这还不算什么,你还没用过UFS呢!”小明一下子好奇起来…

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解

【Spring Cloud系统】- 轻量级高可用工具Keepalive详解 文章目录 【Spring Cloud系统】- 轻量级高可用工具Keepalive详解一、概述二、Keepalive分类2.1 TCP的keepalive2.2 HTTP的keep-alive2.3 TCP的 KeepAlive 和 HTTP的 Keep-Alive区别 三、nginx的keepalive配置3.1 nginx保持…

初出茅庐的小李博客之根据编译时间生成软件版本号

为什么要软件版本号呢? 生成软件版本号是在软件开发和维护过程中非常重要的一项任务,它有很多意义和好处,同时也有多种常见的方法。 标识和追踪:软件版本号是唯一的标识符,用于区分不同版本的软件。这有助于开发人员和…

【案例分享】部署华为防火墙确保园区出口安全

【微|信|公|众|号:厦门微思网络】 部署华为防火墙确保园区出口安全案例 本案例将以园区典型组网为例,主要介绍园区出口安全的部署。具体业务安全要求如下: 内网用户可以正常访问Internet资源,但只能访问教育/科学类、搜索/门户类网…

【计算机组成 课程笔记】5.2 处理器的设计步骤(2)

课程链接: 计算机组成_北京大学_中国大学MOOC(慕课) 5 - 3 - 503-运算指令的控制信号(14-58--)_哔哩哔哩_bilibili 【计算机组成 课程笔记】5.1 处理器的设计步骤-CSDN博客 中介绍了处理器的设计步骤中的前三步,接下来我们继续介绍…

一文了解大模型工作原理——以ChatGPT为例

文章目录 写在前面1.Tansformer架构模型2.ChatGPT原理3.提示学习与大模型能力的涌现3.1 提示学习3.2 上下文学习3.3 思维链 4.行业参考建议4.1 拥抱变化4.2 定位清晰4.3 合规可控4.4 经验沉淀 写在前面 2022年11月30日,ChatGPT模型问世后,立刻在全球范围…

模电课程设计

主要内容跟本科实验关系很大,可以用来借鉴。 包含文件有:实验报告、Multisim仿真文件,资料很全,有问题可以私信 目录 1、模电课设:用Multisim简单了解二极管 2、模电课设:用Multisim简析三极管与场效应…

Python基础语法练习

输出欢迎信息 方法一: 定义变量赋值并输出,用将变量和字符拼接 username "EMT" print("Welcome,” username)方法二: 用format函数格式化输出变量,并替换{}中的内容 username "EMT" print("welcom…

vue3_动态添加路由,以及路由刷新后页面丢失问题

首先,是要将权限数据本地持久化存储 接着在router文件夹index.js中引入store中的权限数据,并导出一个方法,判断权限当中的数据,并跟roleEnum路由规则匹配,匹配上之后则addRoute() 在登录之后调用这个方法,动…

django添加数据库字段进行数据迁移

1.修改view.py里面的变量 2.在model.py新增字段 3.打开terminal并将环境切到项目所在环境,切换方式为 4.执行命令 python manage.py makemigrations backend python manage.py migrate

CSP 201403-1 相反数

答题 用两个优先队列,一个记录正数升序排序,一个记录负数降序排序,然后在两个队列都不为空的情况下取二者top相加与0比较大小,如果等于0,那么相反数的数目增加一对并同时弹出队列,如果小于0,那…

智能称重解决方案

智能称重解决方案 在现代制造业中,确保产品质量是至关重要的。尤其是在装配产线中,经常面临着漏装、少装等装箱异常问题,这可能导致产品不合格、客户投诉以及损失。为了应对这一挑战,我们需要开发一套智能监控系统,采…

PostgreSQL Page结构

Page结构 在数据文件(堆表、索引、自由空间映射和可见性映射)内部,它被划分为固定长度的page(或block),默认为 8192 字节(8 KB)。每个文件中的页面从 0 开始顺序编号,这…

管理类联考——数学——汇总篇——知识点突破——应用题——线性规划

⛲️ 一、考点讲解 线性规划特征 线性规划是运筹学中辅助人们进行科学管理的一种数学方法。线性规划所研究的是:在一定条件下,合理安排人力物力等资源,使经济效果达到最好。一般地,求线性目标函数在线性约束条件下的最大值或最小…

Shell编程之sort

sort 命令将文件的每一行作为比较对象,通过将不同行进行相互比较,从而得到最终结果。从首字符开始,依次按ASCII码值进行比较,最后将结果按升序输出。 基本语法 sort (选项)(参数) 常用选项 常用选项 -n根据字符串的数字比较-r…

多功能批量剪辑软件一天剪辑1000条原创视频

下面一个视频用了呆头鹅批量剪辑软件播放量竟然能达到100多万。 他是怎么做到的呢?下面我给大家详细的说一下 ​ 在短视频平台开展业务,需具备批量制作视频的能力,为了超越同行,需大量更新作品,争取更多曝光。素…

pycharm打开远程宿主机或远程docker文件夹目录方法,以及设置代码同步

pycharm打开远程宿主机或远程docker文件夹目录方法,以及设置代码同步_pycharm怎么查看服务器目录_Sisyphus~~的博客-CSDN博客1.如何显示远程的文件夹目录2.如何设置代码同步_pycharm怎么查看服务器目录https://blog.csdn.net/weixin_62321285/article/details/12740…