2016-03-01 184 views
0

我們的項目使用這個apns provider運行在centos 6.4上推送oofline味精。紅寶石操作與紅寶石阻止ppoll

apns提供程序剛剛從redpop隊列中讀取brpop,然後重新格式化數據併發送到apms msg到Apple推送服務。

最近,我遇到了APN提供商不讀從Redis的隊列中味精的問題,我只是與strace過程:

異常strace的結果:

tcp  0  0 ::1:39688     ::1:6379     ESTABLISHED 29452/ruby   
[[email protected]]# strace -p 29452 
Process 29452 attached - interrupt to quit 
ppoll([{fd=56, events=POLLIN}], 1, NULL, NULL, 8 

正常strace的結果:

clock_gettime(CLOCK_MONOTONIC, {9266059, 349937955}) = 0 
select(9, [8], NULL, NULL, {6, 0})  = 1 (in [8], left {3, 976969}) 
fcntl64(8, F_GETFL)      = 0x802 (flags O_RDWR|O_NONBLOCK) 
read(8, "*-1\r\n", 1024)    = 5 
write(8, "*3\r\n$5\r\nbrpop\r\n$9\r\napn_queue\r\n$1"..., 37) = 37 
fcntl64(8, F_GETFL)      = 0x802 (flags O_RDWR|O_NONBLOCK) 
read(8, 0x9a0e5d8, 1024)    = -1 EAGAIN (Resource temporarily unavailable) 
clock_gettime(CLOCK_MONOTONIC, {9266061, 374086306}) = 0 
select(9, [8], NULL, NULL, {6, 0}^C <unfinished ...> 
Process 20493 detached 

這裏是相關的代碼:

loop do 
     begin 
      message = @redis.brpop(self.queue, 1) 
      if message 
       APN.log(:info, "---------->#{message} ----------->\n") 
       @notification = APN::Notification.new(JSON.parse(message.last,:symbolize_names => true)) 

       send_notification 
      end 
     rescue Exception => e 
      if e.class == Interrupt || e.class == SystemExit 
      APN.log(:info, 'Shutting down...') 
      exit(0) 
      end 

      APN.log(:error, "class: #{e.class} Encountered error: #{e}, backtrace #{e.backtrace}") 

      APN.log(:info, 'Trying to reconnect...') 
      client.connect! 
      APN.log(:info, 'Reconnected') 

      client.push(@notification) 
     end 
     end 

此問題發生不定期,期間時間可能是一個或兩個月。

我覺得代碼邏輯是對的,猜測系統網絡可能會影響編程的正常運行。

當我使用pkill [pid]殺死程序時,它只是恢復正常的開始從隊列中讀msg開始。

現在我不知道如何分析問題,所以我必須使用cron重新啓動或每隔一段時間發送一次kill信號給程序。 :(

每個人都可以有想法來處理這個問題?

回答

0

您在零超時您異常strace的結果ppoll使用。 正確的方法是

const struct timespec timeout = { .tv_sec = 10, .tv_nsec = 0 }; 
struct pollfd myfds; 
myfds.fd = fd; 
myfds.events = POLLIN; 
myfds.revents = 0; 
retresult = ppoll(&myfds, 1,&timeout,NULL); 

這將給10秒延時10秒一次完成其返回下一個代碼。