摘要
万万没想到,最近的一个任务居然在一周没有解决,弄得周六在家忙了一天,还没完成,直到周日早上灵光一闪,才完成了。坦白讲,我已经好久没有过这种体验了,被一个技术问题困扰了好几天,如此这般茫然失措,不过好在最后问题解决了。虽然这个任务可能你不会遇到特别相似的,但是我还是想把问题的解决过程分享给大家,顺便聊聊如何解决技术问题。
问题背景
需要将一个开源的python项目接入到公司的微服务体系(主要是java)中。开源的项目下文统称opa
。opa
项目底层依赖一些c++库,比如openImageIO。
问题分析
接到这个任务时,其实我是比较慌的,时间比较紧张,差不多一周的时间就得完成。结合自身的情况,评估这项任务还是存在一些挑战。主要在于
- 我已经几年没有写过python代码,c++了,比较陌生。
- 缺乏构建复杂docker image的经验
- 没有接入python语言到微服务体系的经验
- 独自作战,没有可咨询的对象
首先我将这项任务做了一些拆解,并评估了下难度,满分5星
- 搭建python开发环境,需要在本地跑起个
opa
项目,进行开发,调试。 *** - 将
opa
项目改造成为一个web项目,提供restful接口。** - 将服务注册到服务中心 *
- 提供java client给外部调用 *
- build docker image,将服务部署到k8s上。 ***
万万没想到,这个任务在解决过程居然遇到这么多的问题
解决过程
将opa
项目改造成为一个web项目
这个任务一开始评估困难指数3星,实际发现虽然有一定难度,但是借助搜索引擎就能完成,综合指数2星吧,实际花费时间1d
IDE: pycharm
环境: py2/py3
包构建: pip
遇到的问题主要有
python2,python3的问题
开发环境安装的是py3,opa
project是py2项目,所以借助工具转换了下
python转python3
包版本问题
这个对于我这个写java来说,python的包管理简直是扯淡了,用震惊形容毫不过分。
槽点
- 没有项目依赖包的文件
- 包不用指定版本
不过因为这个项目引入的包不多,我没有过多纠结这点,就单个单个的安装起来了。如果是正儿八经的需要维护的项目,python现在也有了,有需要的移步
包管理工具了
将opa
项目改造成为一个web项目
这个任务完成的比预期快,使用flask
包,借助flask 教程
实际花费一天就搞定了
将服务注册到服务中心 && 提供java client给外部调用
这块内容问题不大,纯体力活,轻车熟路,一天解决
build docker image,将服务部署到k8s上
这一步一开始评估3星,没想到真的折磨到我了,花了两个工作日都没有解决。弄到周末才解决。遇到的问题10+,凭一些笔记记录了下一些
1.pip install
时发现没有某个包的版本,版本提升,然后需要python3,其实环境是python2
https://xbuba.com/questions/56970211
最后通过指定版本解决
pip install -i https://mirrors.aliyun.com/pypi/simple numpy==1.16.4
2.网络的问题
这个问题折磨的我痛不欲生,欲哭无泪。因为需要验证构建是否正确,要反复的build image,每次install 各种package, pip install
python包,需要半小时才完成的了。在家连vpn,网络更加慢,时间更长,这让我无数次拷问自己,都2019年了,我居然还在被网络带宽困扰,人活着的意义到底是为了什么,我为什么要把我美好的人生浪费在这里。
这个问题主要通过3方面解决
- docker multi stage build
构建多个docker base镜像,然后from base镜像,这样可以减少image的构建时间
- 更改下载软件的地址源
比如apt,yum的,pip 的。
- 将另外一些需要wget的包下载下来,扔到内网,访问内网地址
3.docker image 构建的from
需要构建基于公司内部的java base image,以及python 项目的base image。
一开始想当然的
FROM opa.image
FROM company.image
事实上docker只能从一个base继承,第一个FROM 会被忽略掉。所以需要使用多阶段构建,将前一层的内容copy到新的一层
详情可参考multi-stage build
4.c++ 动态链接库的问题
多阶段构建时候,将opa
image 内容copy过来时,执行bin/时报错。缺少c++的库。c++的库需要make到内核的,直接copy文件没有用。
5.ubuntu,centos 的问题
公司的镜像都是基于centos系统,开源的基于ubuntu的,语法上有些不兼容。
终极解决
困扰我最大的问题就是docker image的问题构建问题,如何基于两个base image,构建一个能允许c++,python,java的 docker container。最后问题的解决来自于一觉醒来的灵光一闪。
项目需要的环境大致如下图
前期我一直纠结于各种问题
- ubuntu,centos
- 各种包install出错的问题
- 包版本的问题
- c++ 库make install
- 网络下载问题
这么多的问题交织在一起,头脑不清晰。
困扰我最大的问题就是docker image的问题构建问题,如何基于两个base image,构建一个能允许c++,python,java的 docker container。最后问题的解决来自于一觉醒来的灵光一闪。
因为对于我,主要难点是在于原有项目的docker image构建,而公司里面的镜像和这次新加的代码,主要就是java运行时环境,
jar 包的run,以及pip install 几个python包,这些都比较简单。
所以换了一个思路,不再基于公司的image的centos环境,而是基于opa
的image,这样可以不动原来的image。相当于把那些我不熟悉的东西全都屏蔽了。
构建一个base image
FROM company.image AS builder
// 将环境基于原来的image
FROM base.image
// copy java环境到image
COPY --from=builder /usr/lib/jvm/jdk1.8.0_172 /usr/lib/jvm/jdk1.8.0_172
然后在base image基础上构建python环境。最后问题解决。
总结
在解决这个问题的过程中,我总结一个一些基本的原则,可能会帮助到你解决问题
了解自己的技术水平,把握节奏
在开始解决任务时,评估好难点,在解决过程中不断与预估时间对比,超出了预期,需要及时调整,
牢牢掌握住任务的节奏,确保一切都在可控之中。分清问题主次
你可能会遇到很多问题,这些问题深究下去又会引发很多的问题,如此深度遍历,会导致任务延期,有深深的挫败感。
对问题分类,区分出来哪些是必须要解决的,哪些是可以忽略的。
只解决必须解决的问题,不是必须的但是你有兴趣的问题,记录下来,后续深究。分而治之
你解决的任务可能别人都没做过,网络上也找不到答案。需要将任务拆散,将有很多背景的复杂问题抽象出来,简单化,去咨询有过相关经验的人,可以使得沟通更有效率,解决问题的速度更快
关注公众号【方丈的寺院】,第一时间收到文章的更新,与方丈一起开始技术修行之路
参考
https://xbuba.com/questions/56970211
https://docs.docker.com/develop/develop-images/multistage-build/