主頁 >  其他 > Istio 運維實戰系列(1):應用容器對 Envoy Sidecar 的啟動依賴問題

Istio 運維實戰系列(1):應用容器對 Envoy Sidecar 的啟動依賴問題

2020-09-10 18:22:47 其他

本系列文章將介紹用戶從 Spring Cloud,Dubbo 等傳統微服務框架遷移到 Istio 服務網格時的一些經驗,以及在使用 Istio 程序中可能遇到的一些常見問題的解決方法,

故障現象

該問題的表現是安裝了 sidecar proxy 的應用在啟動后的一小段時間內無法通過網路訪問 pod 外部的其他服務,例如外部的 HTTP,MySQL,Redis等服務,如果應用沒有對依賴服務的例外進行容錯處理,該問題還常常會導致應用啟動失敗,下面我們以該問題導致的一個典型故障的分析程序為例對該問題的原因進行說明,

典型案例:某運維同學反饋:昨天晚上 Istio 環境中應用的心跳檢測報 connect reset,然后服務重啟了,懷疑是 Istio 環境中網路不穩定導致了服務重啟,

故障分析

根據運維同學的反饋,該 pod 曾多次重啟,因此我們先用 kubectl logs --previous 命令查詢 awesome-app 容器最后一次重啟前的日志,以從日志中查找其重啟的原因,

kubectl logs --previous awesome-app-cd1234567-gzgwg -c awesome-app

從日志中查詢到了其重啟前最后的錯誤資訊如下:

Logging system failed to initialize using configuration from 'http://log-config-server:12345/******/logback-spring.xml'
java.net.ConnectException: Connection refused (Connection refused)
        at java.net.PlainSocketImpl.socketConnect(Native Method)
        at java.net.AbstractPlainSocketImpl.doConnect(AbstractPlainSocketImpl.java:350)
        at java.net.AbstractPlainSocketImpl.connectToAddress(AbstractPlainSocketImpl.java:206)

從錯誤資訊可以得知,應用行程在啟動時試圖通過 HTTP 協議從配置中心拉取 logback 的配置資訊,但該操作由于網路例外失敗了,導致應用行程啟動失敗,最終導致容器重啟,

是什么導致了網路例外呢?我們再用 Kubectl get pod 命令查詢 Pod 的運行狀態,嘗試找到更多的線索:

kubectl get pod awesome-app-cd1234567-gzgwg  -oyaml

命令輸出的 pod 詳細內容如下,該 yaml 片段省略了其他無關的細節,只顯示了 lastState 和 state 部分的容器狀態資訊,

containerStatuses:
  - containerID: 
    lastState:
      terminated:
        containerID: 
        exitCode: 1
        finishedAt: 2020-09-01T13:16:23Z
        reason: Error
        startedAt: 2020-09-01T13:16:22Z
    name: awesome-app
    ready: true
    restartCount: 2
    state:
      running:
        startedAt: 2020-09-01T13:16:36Z
  - containerID: 
    lastState: {}
    name: istio-proxy
    ready: true
    restartCount: 0
    state:
      running:
        startedAt: 2020-09-01T13:16:20Z
  hostIP: 10.0.6.161

從該輸出可以看到 pod 中的應用容器 awesome-app 重啟了兩次,整理該 pod 中 awesome-app 應用容器和 istio-proxy sidecar 容器的啟動和終止的時間順序,可以得到下面的時間線:

  1. 2020-09-01T13:16:20Z istio-proxy 啟動
  2. 2020-09-01T13:16:22Z awesome-app 上一次啟動時間
  3. 2020-09-01T13:16:23Z awesome-app 上一次例外退出時間
  4. 2020-09-01T13:16:36Z awesome-app 最后一次啟動,以后就一直正常運行

可以看到在 istio-proxy 啟動2秒后,awesome-app 啟動,并于1秒后例外退出,結合前面的日志資訊,我們知道這次啟動失敗的直接原因是應用訪問配置中心失敗導致,在 istio-proxy 啟動16秒后,awesome-app 再次啟動,這次啟動成功,之后一直正常運行,

istio-proxy 啟動和 awesome-app 上一次例外退出的時間間隔很短,只有2秒鐘,因此我們基本可以判斷此時 istio-proxy 尚未啟動初始化完成,導致 awesome-app 不能通過istio-proxy 連接到外部服務,導致其啟動失敗,待 awesome-app 于 2020-09-01T13:16:36Z 再次啟動時,由于 istio-proxy 已經啟動了較長時間,完成了從 pilot 獲取動態配置的程序,因此 awesome-app 向 pod 外部的網路訪問就正常了,

如下圖所示,Envoy 啟動后會通過 xDS 協議向 pilot 請求服務和路由配置資訊,Pilot 收到請求后會根據 Envoy 所在的節點(pod或者VM)組裝配置資訊,包括 Listener、Route、Cluster等,然后再通過 xDS 協議下發給 Envoy,根據 Mesh 的規模和網路情況,該配置下發程序需要數秒到數十秒的時間,由于初始化容器已經在 pod 中創建了 Iptables rule 規則,因此這段時間內應用向外發送的網路流量會被重定向到 Envoy ,而此時 Envoy 中尚沒有對這些網路請求進行處理的監聽器和路由規則,無法對此進行處理,導致網路請求失敗,(關于 Envoy sidecar 初始化程序和 Istio 流量管理原理的更多內容,可以參考這篇文章 Istio流量管理實作機制深度決議) img

解決方案

在應用啟動命令中判斷 Envoy 初始化狀態

從前面的分析可以得知,該問題的根本原因是由于應用行程對 Envoy sidecar 配置初始化的依賴導致的,因此最直接的解決思路就是:在應用行程啟動時判斷 Envoy sidecar 的初始化狀態,待其初始化完成后再啟動應用行程,

Envoy 的健康檢查介面 localhost:15020/healthz/ready 會在 xDS 配置初始化完成后才回傳 200,否則將回傳 503,因此可以根據該介面判斷 Envoy 的配置初始化狀態,待其完成后再啟動應用容器,我們可以在應用容器的啟動命令中加入呼叫 Envoy 健康檢查的腳本,如下面的配置片段所示,在其他應用中使用時,將 start-awesome-app-cmd 改為容器中的應用啟動命令即可,

apiVersion: apps/v1
kind: Deployment
metadata:
  name: awesome-app-deployment
spec:
  selector:
    matchLabels:
      app: awesome-app
  replicas: 1
  template:
    metadata:
      labels:
        app: awesome-app
    spec:
      containers:
      - name: awesome-app
        image: awesome-app
        ports:
        - containerPort: 80
        command: ["/bin/bash", "-c"]
        args: ["while [[ \"$(curl -s -o /dev/null -w ''%{http_code}'' localhost:15020/healthz/ready)\" != '200' ]]; do echo Waiting for Sidecar;sleep 1; done; echo Sidecar available; start-awesome-app-cmd"]

該流程的執行順序如下:

  1. Kubernetes 啟動 應用容器,
  2. 應用容器啟動腳本中通過 curl get localhost:15020/healthz/ready 查詢 Envoy sidcar 狀態,由于此時 Envoy sidecar 尚未就緒,因此該腳本會不斷重試,
  3. Kubernetes 啟動 Envoy sidecar,
  4. Envoy sidecar 通過 xDS 連接 Pilot,進行配置初始化,
  5. 應用容器啟動腳本通過 Envoy sidecar 的健康檢查介面判斷其初始化已經完成,啟動應用行程,

該方案雖然可以規避依賴順序的問題,但需要對應用容器的啟動腳本進行修改,對 Envoy 的健康狀態進行判斷,更理想的方案應該是應用對 Envoy sidecar 不感知,

通過 pod 容器啟動順序進行控制

通過閱讀 Kubernetes 原始碼 ,我們可以發現當 pod 中有多個容器時,Kubernetes 會在一個執行緒中依次啟動這些容器,如下面的代碼片段所示:

	// Step 7: start containers in podContainerChanges.ContainersToStart.
	for _, idx := range podContainerChanges.ContainersToStart {
		start("container", containerStartSpec(&pod.Spec.Containers[idx]))
  }

因此我們可以在向 pod 中注入 Envoy sidecar 時將 Envoy sidecar 放到應用容器之前,這樣 Kubernetes 會先啟動 Envoy sidecar,再啟動應用容器,但是還有一個問題,Envoy 啟動后我們并不能立即啟動應用容器,還需要等待 xDS 配置初始化完成,這時我們就可以采用容器的 postStart lifecycle hook來達成該目的,Kubernetes 會在啟動容器后呼叫該容器的 postStart hook,postStart hook 會阻塞 pod 中的下一個容器的啟動,直到 postStart hook 執行完成,因此如果在 Envoy sidecar 的 postStart hook 中對 Envoy 的配置初始化狀態進行判斷,待完成初始化后再回傳,就可以保證 Kubernetes 在 Envoy sidecar 配置初始化完成后再啟動應用容器,該流程的執行順序如下:

  1. Kubernetes 啟動 Envoy sidecar ,
  2. Kubernetes 執行 postStart hook,
  3. postStart hook 通過 Envoy 健康檢查介面判斷其配置初始化狀態,直到 Envoy 啟動完成 ,
  4. Kubernetes 啟動應用容器,

Istio 已經在 1.7 中合入了該修復方案,參見 Allow users to delay application start until proxy is ready #24737,

插入 sidecar 后的 pod spec 如下面的 yaml 片段所示,postStart hook 配置的 pilot-agent wait 命令會持續呼叫 Envoy 的健康檢查介面 '/healthz/ready' 檢查其狀態,直到 Envoy 完成配置初始化,這篇文章Delaying application start until sidecar is ready中介紹了更多關于該方案的細節,

apiVersion: v1
kind: Pod
metadata:
  name: sidecar-starts-first
spec:
  containers:
  - name: istio-proxy
    image: 
    lifecycle:
      postStart:
        exec:
          command:
          - pilot-agent
          - wait
  - name: application
    image: my-application

該方案在不對應用進行修改的情況下比較完美地解決了應用容器和 Envoy sidecar 初始化的依賴問題,但是該解決方案對 Kubernetes 有兩個隱式依賴條件:Kubernetes 在一個執行緒中按定義順序依次啟動 pod 中的多個容器,以及前一個容器的 postStart hook 執行完畢后再啟動下一個容器,這兩個前提條件在目前的 Kuberenetes 代碼實作中是滿足的,但由于這并不是 Kubernetes的 API 規范,因此該前提在將來 Kubernetes 升級后很可能被打破,導致該問題再次出現,

Kubernetes 支持定義 pod 中容器之間的依賴關系

為了徹底解決該問題,避免 Kubernetes 代碼變動后該問題再次出現,更合理的方式應該是由 Kubernetes 支持顯式定義 pod 中一個容器的啟動依賴于另一個容器的健康狀態,目前 Kubernetes 中已經有一個 issue Support startup dependencies between containers on the same Pod #65502 對該問題進行跟蹤處理,如果 Kubernetes 支持了該特性,則該流程的執行順序如下:

  1. Kubernetes 啟動 Envoy sidecar 容器,
  2. Kubernetes 通過 Envoy sidecar 容器的 readiness probe 檢查其狀態,直到 readiness probe 反饋 Envoy sidecar 已經 ready,即已經初始化完畢,
  3. Kubernetes 啟動應用容器,

解耦應用服務之間的啟動依賴關系

以上幾個解決方案的思路都是控制 pod 中容器的啟動順序,在 Envoy sidecar 初始化完成后再啟動應用容器,以確保應用容器啟動時能夠通過網路正常訪問其他服務,但這些方案只是『頭痛醫頭,腳痛醫腳』,是治標不治本的方法,因為即使 pod 中對外的網路訪問沒有問題,應用容器依賴的其他服務也可能由于尚未啟動,或者某些問題而不能在此時正常提供服務,要徹底解決該問題,我們需要解耦應用服務之間的啟動依賴關系,使應用容器的啟動不再強依賴其他服務,

在一個微服務系統中,原單體應用中的各個業務模塊被拆分為多個獨立行程(服務),這些服務的啟動順序是隨機的,并且服務之間通過不可靠的網路進行通信,微服務多行程部署、跨行程網路通信的特定決定了服務之間的呼叫出現例外是一個常見的情況,為了應對微服務的該特點,微服務的一個基本的設計原則是 "design for failure",即需要以優雅的方式應對可能出現的各種例外情況,當在微服務行程中不能訪問一個依賴的外部服務時,需要通過重試、降級、超時、斷路等策略對例外進行容錯處理,以盡可能保證系統的正常運行,

Envoy sidecar 初始化期間網路暫時不能訪問的情況只是放大了微服務系統未能正確處理服務依賴的問題,即使解決了 Envoy sidecar 的依賴順序,該問題依然存在,例如在本案例中,配置中心也是一個獨立的微服務,當一個依賴配置中心的微服務啟動時,配置中心有可能尚未啟動,或者尚未初始化完成,在這種情況下,如果在代碼中沒有對該例外情況進行處理,也會導致依賴配置中心的微服務啟動失敗,在一個更為復雜的系統中,多個微服務行程之間可能存在網狀依賴關系,如果沒有按照 "design for failure" 的原則對微服務進行容錯處理,那么只是將整個系統啟動起來就將是一個巨大的挑戰,對于本例而言,可以采用一個類似這樣的簡單容錯策略:先用一個預設的 logback 配置啟動應用行程,并在啟動后對配置中心進行重試,待連接上配置中心后,再使用配置中心下發的配置對 logback 進行設定,

小結

應用容器對 Envoy Sidecar 啟動依賴問題的典型表現是應用容器在剛啟動的一小段時間內呼叫外部服務失敗,原因是此時 Envoy sidecar 尚未完成 xDS 配置的初始化,因此不能為應用容器轉發網路請求,該呼叫失敗可能導致應用容器不能正常啟動,此問題的根本原因是微服務應用中對依賴服務的呼叫失敗沒有進行合理的容錯處理,對于遺留系統,為了盡量避免對應用的影響,我們可以通過在應用啟動命令中判斷 Envoy 初始化狀態的方案,或者升級到 Istio 1.7 來緩解該問題,但為了徹底解決服務依賴導致的錯誤,建議參考 "design for failure" 的設計原則,解耦微服務之間的強依賴關系,在出現暫時不能訪問一個依賴的外部服務的情況時,通過重試、降級、超時、斷路等策略進行處理,以盡可能保證系統的正常運行,

參考檔案

  • App container unable to connect to network before sidecar is fully running #11130(https://github.com/istio/istio/issues/11130)
  • Delaying application start until sidecar is ready(https://medium.com/@marko.luksa/delaying-application-start-until-sidecar-is-ready-2ec2d21a7b74)
  • Kubernetes Container Lifecycle Hooks(https://kubernetes.io/docs/concepts/containers/container-lifecycle-hooks/)
  • Istio流量管理實作機制深度決議 (https://zhaohuabing.com/post/2018-09-25-istio-traffic-management-impl-intro/)

【騰訊云原生】云說新品、云研新術、云游新活、云賞資訊,掃碼關注同名公眾號,及時獲取更多干貨!!

轉載請註明出處,本文鏈接:https://www.uj5u.com/qita/3045.html

標籤:其他

上一篇:關于圖片渲染的程序

下一篇:詳細教程丨使用Prometheus和Thanos進行高可用K8S監控

標籤雲
其他(157675) Python(38076) JavaScript(25376) Java(17977) C(15215) 區塊鏈(8255) C#(7972) AI(7469) 爪哇(7425) MySQL(7132) html(6777) 基礎類(6313) sql(6102) 熊猫(6058) PHP(5869) 数组(5741) R(5409) Linux(5327) 反应(5209) 腳本語言(PerlPython)(5129) 非技術區(4971) Android(4554) 数据框(4311) css(4259) 节点.js(4032) C語言(3288) json(3245) 列表(3129) 扑(3119) C++語言(3117) 安卓(2998) 打字稿(2995) VBA(2789) Java相關(2746) 疑難問題(2699) 细绳(2522) 單片機工控(2479) iOS(2429) ASP.NET(2402) MongoDB(2323) 麻木的(2285) 正则表达式(2254) 字典(2211) 循环(2198) 迅速(2185) 擅长(2169) 镖(2155) 功能(1967) .NET技术(1958) Web開發(1951) python-3.x(1918) HtmlCss(1915) 弹簧靴(1913) C++(1909) xml(1889) PostgreSQL(1872) .NETCore(1853) 谷歌表格(1846) Unity3D(1843) for循环(1842)

熱門瀏覽
  • 網閘典型架構簡述

    網閘架構一般分為兩種:三主機的三系統架構網閘和雙主機的2+1架構網閘。 三主機架構分別為內端機、外端機和仲裁機。三機無論從軟體和硬體上均各自獨立。首先從硬體上來看,三機都用各自獨立的主板、記憶體及存盤設備。從軟體上來看,三機有各自獨立的作業系統。這樣能達到完全的三機獨立。對于“2+1”系統,“2”分為 ......

    uj5u.com 2020-09-10 02:00:44 more
  • 如何從xshell上傳檔案到centos linux虛擬機里

    如何從xshell上傳檔案到centos linux虛擬機里及:虛擬機CentOs下執行 yum -y install lrzsz命令,出現錯誤:鏡像無法找到軟體包 前言 一、安裝lrzsz步驟 二、上傳檔案 三、遇到的問題及解決方案 總結 前言 提示:其實很簡單,往虛擬機上安裝一個上傳檔案的工具 ......

    uj5u.com 2020-09-10 02:00:47 more
  • 一、SQLMAP入門

    一、SQLMAP入門 1、判斷是否存在注入 sqlmap.py -u 網址/id=1 id=1不可缺少。當注入點后面的引數大于兩個時。需要加雙引號, sqlmap.py -u "網址/id=1&uid=1" 2、判斷文本中的請求是否存在注入 從文本中加載http請求,SQLMAP可以從一個文本檔案中 ......

    uj5u.com 2020-09-10 02:00:50 more
  • Metasploit 簡單使用教程

    metasploit 簡單使用教程 浩先生, 2020-08-28 16:18:25 分類專欄: kail 網路安全 linux 文章標簽: linux資訊安全 編輯 著作權 metasploit 使用教程 前言 一、Metasploit是什么? 二、準備作業 三、具體步驟 前言 Msfconsole ......

    uj5u.com 2020-09-10 02:00:53 more
  • 游戲逆向之驅動層與用戶層通訊

    驅動層代碼: #pragma once #include <ntifs.h> #define add_code CTL_CODE(FILE_DEVICE_UNKNOWN,0x800,METHOD_BUFFERED,FILE_ANY_ACCESS) /* 更多游戲逆向視頻www.yxfzedu.com ......

    uj5u.com 2020-09-10 02:00:56 more
  • 北斗電力時鐘(北斗授時服務器)讓網路資料更精準

    北斗電力時鐘(北斗授時服務器)讓網路資料更精準 北斗電力時鐘(北斗授時服務器)讓網路資料更精準 京準電子科技官微——ahjzsz 近幾年,資訊技術的得了快速發展,互聯網在逐漸普及,其在人們生活和生產中都得到了廣泛應用,并且取得了不錯的應用效果。計算機網路資訊在電力系統中的應用,一方面使電力系統的運行 ......

    uj5u.com 2020-09-10 02:01:03 more
  • 【CTF】CTFHub 技能樹 彩蛋 writeup

    ?碎碎念 CTFHub:https://www.ctfhub.com/ 筆者入門CTF時時剛開始刷的是bugku的舊平臺,后來才有了CTFHub。 感覺不論是網頁UI設計,還是題目質量,賽事跟蹤,工具軟體都做得很不錯。 而且因為獨到的金幣制度的確讓人有一種想去刷題賺金幣的感覺。 個人還是非常喜歡這個 ......

    uj5u.com 2020-09-10 02:04:05 more
  • 02windows基礎操作

    我學到了一下幾點 Windows系統目錄結構與滲透的作用 常見Windows的服務詳解 Windows埠詳解 常用的Windows注冊表詳解 hacker DOS命令詳解(net user / type /md /rd/ dir /cd /net use copy、批處理 等) 利用dos命令制作 ......

    uj5u.com 2020-09-10 02:04:18 more
  • 03.Linux基礎操作

    我學到了以下幾點 01Linux系統介紹02系統安裝,密碼啊破解03Linux常用命令04LAMP 01LINUX windows: win03 8 12 16 19 配置不繁瑣 Linux:redhat,centos(紅帽社區版),Ubuntu server,suse unix:金融機構,證券,銀 ......

    uj5u.com 2020-09-10 02:04:30 more
  • 05HTML

    01HTML介紹 02頭部標簽講解03基礎標簽講解04表單標簽講解 HTML前段語言 js1.了解代碼2.根據代碼 懂得挖掘漏洞 (POST注入/XSS漏洞上傳)3.黑帽seo 白帽seo 客戶網站被黑帽植入劫持代碼如何處理4.熟悉html表單 <html><head><title>TDK標題,描述 ......

    uj5u.com 2020-09-10 02:04:36 more
最新发布
  • 2023年最新微信小程式抓包教程

    01 開門見山 隔一個月發一篇文章,不過分。 首先回顧一下《微信系結手機號資料庫被脫庫事件》,我也是第一時間得知了這個訊息,然后跟蹤了整件事情的經過。下面是這起事件的相關截圖以及近日流出的一萬條資料樣本: 個人認為這件事也沒什么,還不如關注一下之前45億快遞資料查詢渠道疑似在近日復活的訊息。 訊息是 ......

    uj5u.com 2023-04-20 08:48:24 more
  • web3 產品介紹:metamask 錢包 使用最多的瀏覽器插件錢包

    Metamask錢包是一種基于區塊鏈技術的數字貨幣錢包,它允許用戶在安全、便捷的環境下管理自己的加密資產。Metamask錢包是以太坊生態系統中最流行的錢包之一,它具有易于使用、安全性高和功能強大等優點。 本文將詳細介紹Metamask錢包的功能和使用方法。 一、 Metamask錢包的功能 數字資 ......

    uj5u.com 2023-04-20 08:47:46 more
  • vulnhub_Earth

    前言 靶機地址->>>vulnhub_Earth 攻擊機ip:192.168.20.121 靶機ip:192.168.20.122 參考文章 https://www.cnblogs.com/Jing-X/archive/2022/04/03/16097695.html https://www.cnb ......

    uj5u.com 2023-04-20 07:46:20 more
  • 從4k到42k,軟體測驗工程師的漲薪史,給我看哭了

    清明節一過,盲猜大家已經無心上班,在數著日子準備過五一,但一想到銀行卡里的余額……瞬間心情就不美麗了。最近,2023年高校畢業生就業調查顯示,本科畢業月平均起薪為5825元。調查一出,便有很多同學表示自己又被平均了。看著這一資料,不免讓人想到前不久中國青年報的一項調查:近六成大學生認為畢業10年內會 ......

    uj5u.com 2023-04-20 07:44:00 more
  • 最新版本 Stable Diffusion 開源 AI 繪畫工具之中文自動提詞篇

    🎈 標簽生成器 由于輸入正向提示詞 prompt 和反向提示詞 negative prompt 都是使用英文,所以對學習母語的我們非常不友好 使用網址:https://tinygeeker.github.io/p/ai-prompt-generator 這個網址是為了讓大家在使用 AI 繪畫的時候 ......

    uj5u.com 2023-04-20 07:43:36 more
  • 漫談前端自動化測驗演進之路及測驗工具分析

    隨著前端技術的不斷發展和應用程式的日益復雜,前端自動化測驗也在不斷演進。隨著 Web 應用程式變得越來越復雜,自動化測驗的需求也越來越高。如今,自動化測驗已經成為 Web 應用程式開發程序中不可或缺的一部分,它們可以幫助開發人員更快地發現和修復錯誤,提高應用程式的性能和可靠性。 ......

    uj5u.com 2023-04-20 07:43:16 more
  • CANN開發實踐:4個DVPP記憶體問題的典型案例解讀

    摘要:由于DVPP媒體資料處理功能對存放輸入、輸出資料的記憶體有更高的要求(例如,記憶體首地址128位元組對齊),因此需呼叫專用的記憶體申請介面,那么本期就分享幾個關于DVPP記憶體問題的典型案例,并給出原因分析及解決方法。 本文分享自華為云社區《FAQ_DVPP記憶體問題案例》,作者:昇騰CANN。 DVPP ......

    uj5u.com 2023-04-20 07:43:03 more
  • msf學習

    msf學習 以kali自帶的msf為例 一、msf核心模塊與功能 msf模塊都放在/usr/share/metasploit-framework/modules目錄下 1、auxiliary 輔助模塊,輔助滲透(埠掃描、登錄密碼爆破、漏洞驗證等) 2、encoders 編碼器模塊,主要包含各種編碼 ......

    uj5u.com 2023-04-20 07:42:59 more
  • Halcon軟體安裝與界面簡介

    1. 下載Halcon17版本到到本地 2. 雙擊安裝包后 3. 步驟如下 1.2 Halcon軟體安裝 界面分為四大塊 1. Halcon的五個助手 1) 影像采集助手:與相機連接,設定相機引數,采集影像 2) 標定助手:九點標定或是其它的標定,生成標定檔案及內參外參,可以將像素單位轉換為長度單位 ......

    uj5u.com 2023-04-20 07:42:17 more
  • 在MacOS下使用Unity3D開發游戲

    第一次發博客,先發一下我的游戲開發環境吧。 去年2月份買了一臺MacBookPro2021 M1pro(以下簡稱mbp),這一年來一直在用mbp開發游戲。我大致分享一下我的開發工具以及使用體驗。 1、Unity 官網鏈接: https://unity.cn/releases 我一般使用的Apple ......

    uj5u.com 2023-04-20 07:40:19 more