居然要周末加班才解决这个问题

  • 2019 年 10 月 30 日
  • 筆記

摘要

万万没想到,最近的一个任务居然在一周没有解决,弄得周六在家忙了一天,还没完成,直到周日早上灵光一闪,才完成了。坦白讲,我已经好久没有过这种体验了,被一个技术问题困扰了好几天,如此这般茫然失措,不过好在最后问题解决了。虽然这个任务可能你不会遇到特别相似的,但是我还是想把问题的解决过程分享给大家,顺便聊聊如何解决技术问题。

问题背景

需要将一个开源的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

不得不吐槽下,python3居然不兼容python2的语法,比如print的等。但是python3的语法可以在python2里面跑,这个是有点坑爹
不过2->3是个大版本,的确可以这么干,不破不立,旧的东西不废弃,增加维护成本

包版本问题

这个对于我这个写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++ 动态链接库的问题

多阶段构建时候,将opaimage 内容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环境。最后问题解决。

总结

在解决这个问题的过程中,我总结一个一些基本的原则,可能会帮助到你解决问题

  1. 了解自己的技术水平,把握节奏

    在开始解决任务时,评估好难点,在解决过程中不断与预估时间对比,超出了预期,需要及时调整,
    牢牢掌握住任务的节奏,确保一切都在可控之中。

  2. 分清问题主次
    对问题分类,区分出来哪些是必须要解决的,哪些是可以忽略的。

    你可能会遇到很多问题,这些问题深究下去又会引发很多的问题,如此深度遍历,会导致任务延期,有深深的挫败感。
    只解决必须解决的问题,不是必须的但是你有兴趣的问题,记录下来,后续深究。

  3. 分而治之
    你解决的任务可能别人都没做过,网络上也找不到答案。需要将任务拆散,将有很多背景的复杂问题抽象出来,简单化,去咨询有过相关经验的人,可以使得沟通更有效率,解决问题的速度更快

关注公众号【方丈的寺院】,第一时间收到文章的更新,与方丈一起开始技术修行之路

在这里插入图片描述

参考

https://xbuba.com/questions/56970211

https://docs.docker.com/develop/develop-images/multistage-build/

https://docs.python.org/zh-cn/3.7/library/2to3.html#