91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

Puppet使用ENC報'Could not load external node results for'

發布時間:2020-07-10 17:27:11 來源:網絡 閱讀:818 作者:kinda22 欄目:編程語言

這個問題出現有一段時間了,最開始的時候從一天3-5次左右到最近的一天出現10多次的告警郵件...

因為Puppet同步采取了主動觸發和定時同步兩種策略,幾乎每次的報錯都是在定時同步時出現...

Puppet Server采用雙主結構,Web ui使用Foreman,為了確定這個報錯是出現在那臺服務器上, 通過對源代碼的log增加主機標記最終定位到了這個錯誤只是出現在一臺服務器上...,出現的很偶然,但所有的錯誤標記中,都是它....

Level	Resource	message
err	Puppet	Could not retrieve catalog from remote server: Error 400 on SERVER: Failed when searching for node xxx: 001。,Could not load external node results for xxx: undefined method `inject' for false:FalseClass ::--- false
notice	Puppet	Using cached catalog
err	Puppet	Could not retrieve catalog; skipping run

 

最后面的 :: --- false    其中::是在log中追加的分解符,方便區分, --- false 是返回的output的信息..

 

在Puppet源代碼中 , 通過indirector與enc相關的find方法中可以看到這個find方法接受一個參數 request

 indirector/node/exec.rb 
  def find(request)
    output = super or return nil

    # Translate the output to ruby.
    result = translate(request.key, output)

    create_node(request.key, result)
  end

output 是調用父方法的find

父方法的find會調用enc腳本獲取返回值,如果失敗或調用不成功則為Nil..

這時會繼續通過translate方法,將yaml輸出轉為ruby的對象

如果output為nil,這時yaml在讀取這個數據的時候就會拋出異常,異常就是收到的Puppet郵件告警的內容了。

  def translate(name, output)
    YAML.load(output).inject({}) do |hash, data|                                             
      case data[0]                                                                           
      when String                                                                            
        hash[data[0].intern] = data[1]                                                       
      when Symbol                                                                            
        hash[data[0]] = data[1]                                                              
      else                                                                                   
        raise Puppet::Error, "key is a #{data[0].class}, not a string or symbol"             
      end                                                                                    
                                                                                             
      hash                                                                                   
    end                                                                                      
                                                                                             
  rescue => detail                                                                           
      raise Puppet::Error, "001,Could not load external node results for #{name}: #{detail} ::#{output} "
  end

 

 

羅嗦了一大堆,其實就是node.rb的腳本在通過api取參數的時候,沒有獲得200...導致的。

通過指向一個錯誤的WEB服務器地址,可以看到 開頭--- false。。。。

[root@test puppet]# ruby node1.rb test
--- false
Error retrieving node test: Net::HTTPNotFound

 

分析node.rb

def enc(certname)
  foreman_url      = "#{url}/node/#{certname}?format=yml"
  uri              = URI.parse(foreman_url)
  req              = Net::HTTP::Get.new(uri.request_uri)
  http             = Net::HTTP.new(uri.host, uri.port)
  http.use_ssl     = uri.scheme == 'https'
  if http.use_ssl?
    if SETTINGS[:ssl_ca] && !SETTINGS[:ssl_ca].empty?
      http.ca_file = SETTINGS[:ssl_ca]
      http.verify_mode = OpenSSL::SSL::VERIFY_PEER
    else
      http.verify_mode = OpenSSL::SSL::VERIFY_NONE
    end
    if SETTINGS[:ssl_cert] && !SETTINGS[:ssl_cert].empty? && SETTINGS[:ssl_key] && !SETTINGS[:ssl_key].empty?
      http.cert = OpenSSL::X509::Certificate.new(File.read(SETTINGS[:ssl_cert]))
      http.key  = OpenSSL::PKey::RSA.new(File.read(SETTINGS[:ssl_key]), nil)
    end
  end
  res = http.start { |http| http.request(req) }

  raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"
  res.body
end

腳本的前面都是在構造一個http的對象...,直接看倒數第三行

可以清楚的看到一個判斷,然后拋出異常,沒有任何的重試機制....,為此我很確信我的web,它如果能有一次重試的機會,那么下一次一定能正常獲得返回值,  然后我就給了它很多次的機會。。。

  #raise "Error retrieving node #{certname}: #{res.class}" unless res.code == "200"
  while res.code != "200"
    res = http.start { |http| http.request(req) }
    puts "Error retrieving node #{certname}: #{res.class}"    sleep 3
  end

這時有些人可能會想,while 循環,加3秒重試,,如果一直不成功怎么辦?

在腳本最開頭會有配置timeout的地方,在timeout到了之后,會關閉http連接,然后讀取cache。

 

      # query External node
      begin
        result = ""
        timeout(tsecs) do
          result = enc(certname)
          cache(certname, result)
        end
      rescue TimeoutError, SocketError, Errno::EHOSTUNREACH, Errno::ECONNREFUSED
        # Read from cache, we got some sort of an error.
        result = read_cache(certname)

這段代碼可以很清晰的看出,在timeout沒超時時會調用enc這個方法返回結果,然后在調用cache方法寫入到cache文件

如果超時或http錯誤,則讀取cache,但是這里的異常不包括...,HTTP的...,如果如果是4XX的錯誤,不會觸發讀取cache的異常..


向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

新龙县| 定州市| 晴隆县| 望谟县| 田林县| 古交市| 如东县| 东阳市| 丘北县| 彭泽县| 科技| 郎溪县| 永寿县| 临泉县| 罗城| 全椒县| 沈丘县| 枣阳市| 平昌县| 华宁县| 尖扎县| 拉萨市| 左贡县| 清新县| 五常市| 香河县| 迭部县| 灌阳县| 富裕县| 靖远县| 汝城县| 沛县| 和静县| 云梦县| 马公市| 和平县| 石狮市| 高陵县| 同江市| 雷波县| 南宫市|