1. 程式人生 > >居然要週末加班才解決這個問題

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

摘要

萬萬沒想到,最近的一個任務居然在一週沒有解決,弄得週六在家忙了一天,還沒完成,直到週日早上靈光一閃,才完成了。坦白講,我已經好久沒有過這種體驗了,被一個技術問題困擾了好幾天,如此這般茫然失措,不過好在最後問題解決了。雖然這個任務可能你不會遇到特別相似的,但是我還是想把問題的解決過程分享給大家,順便聊聊如何解決技術問題。

問題背景

需要將一個開源的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.ht