成人无码视频,亚洲精品久久久久av无码,午夜精品久久久久久毛片,亚洲 中文字幕 日韩 无码

資訊專欄INFORMATION COLUMN

Python實現(xiàn)配置熱加載的方法

89542767 / 630人閱讀


  小編寫這篇文章的目的,主要是給大家講解一下,關于實現(xiàn)配置熱加載的方法,具體是怎么操作呢?下面就給大家詳細的解答下。


  背景


  由于最近有相關的工作需求,需要進行增添相關的新功能,實現(xiàn)配置熱加載的功能。所謂的配置熱加載,也就是說當服務收到配置更新消息之后,我們不用重啟服務就可以使用最新的配置去執(zhí)行任務。


  如何實現(xiàn)


  下面我分別采用多進程、多線程、協(xié)程的方式去實現(xiàn)配置熱加載。


  使用多進程實現(xiàn)配置熱加載


  如果我們代碼實現(xiàn)上使用多進程,主進程1來更新配置并發(fā)送指令,任務的調(diào)用是進程2,如何實現(xiàn)配置熱加載呢?


  使用signal信號量來實現(xiàn)熱加載

01.png

  當主進程收到配置更新的消息之后(配置讀取是如何收到配置更新的消息的?這里我們暫不討論),主進程就向進子程1發(fā)送kill信號,子進程1收到kill的信號就退出,之后由信號處理函數(shù)來啟動一個新的進程,使用最新的配置文件來繼續(xù)執(zhí)行任務。


  main函數(shù)


  def main():
  #啟動一個進程執(zhí)行任務
  p1=Process(target=run,args=("p1",))
  p1.start()
  monitor(p1,run)#注冊信號
  processes["case100"]=p1#將進程pid保存
  num=0
  while True:#模擬獲取配置更新
  print(
  f"{multiprocessing.active_children()=},count={len(multiprocessing.active_children())}\n")
  print(f"{processes=}\n")
  sleep(2)
  if num==4:
  kill_process(processes["case100"])#kill當前進程
  if num==8:
  kill_process(processes["case100"])#kill當前進程
  if num==12:
  kill_process(processes["case100"])#kill當前進程
  num+=1

  signal_handler函數(shù)


  def signal_handler(process:Process,func,signum,frame):
  #print(f"{signum=}")
  global counts
  if signum==17:#17 is SIGCHILD
  #這個循環(huán)是為了忽略SIGTERM發(fā)出的信號,避免搶占了主進程發(fā)出的SIGCHILD
  for signame in[SIGTERM,SIGCHLD,SIGQUIT]:
  signal.signal(signame,SIG_DFL)
  print("Launch a new process")
  p=multiprocessing.Process(target=func,args=(f"p{counts}",))
  p.start()
  monitor(p,run)
  processes["case100"]=p
  counts+=1
  if signum==2:
  if process.is_alive():
  print(f"Kill{process}process")
  process.terminate()
  signal.signal(SIGCHLD,SIG_IGN)
  sys.exit("kill parent process")


  完整代碼如下


  #!/usr/local/bin/python3.8
  from multiprocessing import Process
  from typing import Dict
  import signal
  from signal import SIGCHLD,SIGTERM,SIGINT,SIGQUIT,SIG_DFL,SIG_IGN
  import multiprocessing
  from multiprocessing import Process
  from typing import Callable
  from data import processes
  import sys
  from functools import partial
  import time
  processes:Dict[str,Process]={}
  counts=2
  def run(process:Process):
  while True:
  print(f"{process}running...")
  time.sleep(1)
  def kill_process(process:Process):
  print(f"kill{process}")
  process.terminate()
  def monitor(process:Process,func:Callable):
  for signame in[SIGTERM,SIGCHLD,SIGINT,SIGQUIT]:
  #SIGTERM is kill signal.
  #No SIGCHILD is not trigger singnal_handler,
  #No SIGINT is not handler ctrl+c,
  #No SIGQUIT is RuntimeError:reentrant call inside<_io.BufferedWriter name='<stdout>'>
  signal.signal(signame,partial(signal_handler,process,func))
  def signal_handler(process:Process,func,signum,frame):
  print(f"{signum=}")
  global counts
  if signum==17:#17 is SIGTERM
  for signame in[SIGTERM,SIGCHLD,SIGQUIT]:
  signal.signal(signame,SIG_DFL)
  print("Launch a new process")
  p=multiprocessing.Process(target=func,args=(f"p{counts}",))
  p.start()
  monitor(p,run)
  processes["case100"]=p
  counts+=1
  if signum==2:
  if process.is_alive():
  print(f"Kill{process}process")
  process.terminate()
  signal.signal(SIGCHLD,SIG_IGN)
  sys.exit("kill parent process")
  def main():
  p1=Process(target=run,args=("p1",))
  p1.start()
  monitor(p1,run)
  processes["case100"]=p1
  num=0
  while True:
  print(
  f"{multiprocessing.active_children()=},count={len(multiprocessing.active_children())}\n")
  print(f"{processes=}\n")
  time.sleep(2)
  if num==4:
  kill_process(processes["case100"])
  if num==8:
  kill_process(processes["case100"])
  if num==12:
  kill_process(processes["case100"])
  num+=1
  if __name__=='__main__':
  main()

  執(zhí)行結果如下


  multiprocessing.active_children()=[<Process name='Process-1'pid=2533 parent=2532 started>],count=1
  processes={'case100':<Process name='Process-1'pid=2533 parent=2532 started>}
  p1 running...
  p1 running...
  kill<Process name='Process-1'pid=2533 parent=2532 started>
  multiprocessing.active_children()=[<Process name='Process-1'pid=2533 parent=2532 started>],count=1
  processes={'case100':<Process name='Process-1'pid=2533 parent=2532 started>}
  signum=17
  Launch a new process
  p2 running...
  p2 running...
  multiprocessing.active_children()=[<Process name='Process-2'pid=2577 parent=2532 started>],count=1
  processes={'case100':<Process name='Process-2'pid=2577 parent=2532 started>}
  p2 running...
  p2 running...
  multiprocessing.active_children()=[<Process name='Process-2'pid=2577 parent=2532 started>],count=1
  processes={'case100':<Process name='Process-2'pid=2577 parent=2532 started>}
  p2 running...
  p2 running...
  multiprocessing.active_children()=[<Process name='Process-2'pid=2577 parent=2532 started>],count=1
  processes={'case100':<Process name='Process-2'pid=2577 parent=2532 started>}
  p2 running...
  p2 running...
  kill<Process name='Process-2'pid=2577 parent=2532 started>
  signum=17
  Launch a new process
  multiprocessing.active_children()=[<Process name='Process-2'pid=2577 parent=2532 stopped exitcode=-SIGTERM>],count=1
  processes={'case100':<Process name='Process-3'pid=2675 parent=2532 started>}
  p3 running...
  p3 running...
  multiprocessing.active_children()=[<Process name='Process-3'pid=2675 parent=2532 started>],count=1


  總結


  好處:使用信號量可以處理多進程之間通信的問題。


  自媒體培訓


  壞處:代碼不好寫,寫出來代碼不好理解。信號量使用必須要很熟悉,不然很容易自己給自己寫了一個bug.(所有初學者慎用,老司機除外。)


  還有一點不是特別理解的就是process.terminate()發(fā)送出信號是SIGTERM number是15,但是第一次signal_handler收到信號卻是number=17,如果我要去處理15的信號,就會導致前一個進程不能kill掉的問題。歡迎有對信號量比較熟悉的大佬,前來指點迷津,不甚感謝。


  采用multiprocessing.Event來實現(xiàn)配置熱加載


  實現(xiàn)邏輯是主進程1更新配置并發(fā)送指令。進程2啟動調(diào)度任務。


  這時候當主進程1更新好配置之后,發(fā)送指令給進程2,這時候的指令就是用Event一個異步事件通知。


  直接上代碼


  scheduler函數(shù)
  def scheduler():
  while True:
  print('wait message...')
  case_configurations=scheduler_notify_queue.get()
  print(f"Got case configurations{case_configurations=}...")
  task_schedule_event.set()#設置set之后,is_set為True
  print(f"Schedule will start...")
  while task_schedule_event.is_set():#is_set為True的話,那么任務就會一直執(zhí)行
  run(case_configurations)
  print("Clearing all scheduling job...")
  event_scheduler函數(shù)
  def event_scheduler(case_config):
  scheduler_notify_queue.put(case_config)
  print(f"Put cases config to the Queue...")
  task_schedule_event.clear()#clear之后,is_set為False
  print(f"Clear scheduler jobs...")
  print(f"Schedule job...")
  完整代碼如下
  import multiprocessing
  import time
  scheduler_notify_queue=multiprocessing.Queue()
  task_schedule_event=multiprocessing.Event()
  def run(case_configurations:str):
  print(f'{case_configurations}running...')
  time.sleep(3)
  def scheduler():
  while True:
  print('wait message...')
  case_configurations=scheduler_notify_queue.get()
  print(f"Got case configurations{case_configurations=}...")
  task_schedule_event.set()
  print(f"Schedule will start...")
  while task_schedule_event.is_set():
  run(case_configurations)
  print("Clearing all scheduling job...")
  def event_scheduler(case_config:str):
  scheduler_notify_queue.put(case_config)
  print(f"Put cases config to the Queue...")
  task_schedule_event.clear()
  print(f"Clear scheduler jobs...")
  print(f"Schedule job...")
  def main():
  scheduler_notify_queue.put('1')
  p=multiprocessing.Process(target=scheduler)
  p.start()
  count=1
  print(f'{count=}')
  while True:
  if count==5:
  event_scheduler('100')
  if count==10:
  event_scheduler('200')
  count+=1
  time.sleep(1)
  if __name__=='__main__':
  main()
  執(zhí)行結果如下
  wait message...
  Got case configurations case_configurations='1'...
  Schedule will start...
  1 running...
  1 running...
  Put cases config to the Queue...
  Clear scheduler jobs...
  Schedule job...
  Clearing all scheduling job...
  wait message...
  Got case configurations case_configurations='100'...
  Schedule will start...
  100 running...
  Put cases config to the Queue...
  Clear scheduler jobs...
  Schedule job...
  Clearing all scheduling job...
  wait message...
  Got case configurations case_configurations='200'...
  Schedule will start...
  200 running...
  200 running...

  總結


  使用Event事件通知,代碼不易出錯,代碼編寫少,易讀。相比之前信號量的方法,推薦大家多使用這種方式。


  使用多線程或協(xié)程的方式,其實和上述實現(xiàn)方式一致。唯一區(qū)別就是調(diào)用了不同庫中,queue和event.


  #threading
  scheduler_notify_queue=queue.Queue()
  task_schedule_event=threading.Event()
  #async
  scheduler_notify_queue=asyncio.Queue()
  task_schedule_event=asyncio.Event()


  綜上所述,就是小編給大家總結的,關于python方面的一些知識了,希望可以給大家?guī)韼椭?/p>


文章版權歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.hztianpu.com/yun/128005.html

相關文章

  • 【效率專精系列】幾種常見JVM部署技術及實現(xiàn)難點淺談

    摘要:而熱部署技術能夠幫助開發(fā)人員減少重新部署的等待時間。本文的目的為調(diào)研熱部署的技術現(xiàn)狀及其對開發(fā)效率的幫助,并簡單梳理其技術實現(xiàn)的難點。熱部署技術總結熱部署目前有多種技術實現(xiàn)官方開源商業(yè)。 開發(fā)、自測、聯(lián)調(diào)期間代碼可能會被頻繁地修改,通常即使只增加了一行代碼,都需要重啟容器以檢查執(zhí)行效果。而熱部署技術能夠幫助開發(fā)人員減少重新部署的等待時間。本文的目的為調(diào)研熱部署的技術現(xiàn)狀及其對開發(fā)效率的...

    dongfangyiyu 評論0 收藏0
  • 慕課網(wǎng)_《Spring Boot部署》學習總結

    時間:2017年12月01日星期五說明:本文部分內(nèi)容均來自慕課網(wǎng)。@慕課網(wǎng):http://www.imooc.com 教學源碼:無 學習源碼:https://github.com/zccodere/s... 第一章:課程介紹 1-1 課程介紹 熱部署的使用場景 本地調(diào)式 線上發(fā)布 熱部署的使用優(yōu)點 無論本地還是線上,都適用 無需重啟服務器:提高開發(fā)、調(diào)式效率、提升發(fā)布、運維效率、降低運維成本 前置...

    Channe 評論0 收藏0
  • webpack學習(三)—— webpack-dev-server

    摘要:在項目根目錄下創(chuàng)建,通過這個文件來起服務。到這里為止,自動刷新的內(nèi)容基本講完了。注意到一點,目前自動刷新都是刷新整個頁面。其中表示熱加載模塊,表示。后續(xù)我還會進行更深入的學習,希望和大家共同進步。 本文主要介紹以下兩方面的內(nèi)容: webpack-dev-server自動刷新 熱加載(Hot Module Replacement) 自動刷新 webpack-dev-server提供了...

    CKJOKER 評論0 收藏0
  • SpringBoot就是這么簡單

    摘要:熱加載代表的是我們不需要重啟服務器,就能夠類檢測得到,重新生成類的字節(jié)碼文件無論是熱部署或者是熱加載都是基于類加載器來完成的。驗證階段字節(jié)碼文件不會對造成危害準備階段是會賦初始值,并不是程序中的值。 一、SpringBoot入門 今天在慕課網(wǎng)中看見了Spring Boot這么一個教程,這個Spring Boot作為JavaWeb的學習者肯定至少會聽過,但我是不知道他是什么玩意。 只是大...

    whinc 評論0 收藏0

發(fā)表評論

0條評論

最新活動
閱讀需要支付1元查看
<