居然要周末加班才解決這個問題

  • 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#