当前位置: 移动技术网 > 科技>人工智能>VR/AR > RTSP协议视频流媒体安防智能分析平台EasyNVR如何启动多个nignx?

RTSP协议视频流媒体安防智能分析平台EasyNVR如何启动多个nignx?

2020年11月26日  | 移动技术网科技  | 我要评论
Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,因此TSINGSEE青犀视频云边端架构视频智能分析平台在运行时也会使用nginx服务器。部分情况下,EasyNVR启动时只带起来了一个nginx,但是一个nginx的能力不能满足EasyNVR直播转码分发以及存储的需求,因此这时我们需要启动多个nginx。本文就讲一下启动多个Ngin

Nginx是一款轻量级的Web 服务器/反向代理服务器及电子邮件(IMAP/POP3)代理服务器,在BSD-like 协议下发行。其特点是占有内存少,并发能力强,事实上nginx的并发能力在同类型的网页服务器中表现较好,因此TSINGSEE青犀视频云边端架构视频智能分析平台在运行时也会使用nginx服务器。

TSINGSEE2.png

部分情况下,EasyNVR启动时只带起来了一个nginx,但是一个nginx的能力不能满足EasyNVR直播转码分发以及存储的需求,因此这时我们需要启动多个nginx。本文就讲一下启动多个Nginx的方法。

在EasyNVR程序启动的时候,会默认启动一个nginx,我们可以查看这部分代码,仿照这部分代码编写启动多个nginx的代码。

51.png

func Start() (err error) {
  exe := EXE()
  MutliStrart(exe, 0)
  enable := utils.Conf().Section("base_config").Key("multi_nginx_enable").MustBool(false)
  if enable {
     number := utils.Conf().Section("base_config").Key("multi_nginx_number").MustInt()
     for i := 1; i < number; i++ {
        MutliStrart(MultiEXE(i), i)
     }
  }
  return
}

在启动的时候,默认会先启动EasyNVR里面默认的nginx,然后根据配置文件启动多个nginx,参考代码如下:

func MutliStrart(exe string, index int) (err error) {
   if exe == "" {
      err = fmt.Errorf("dss bin path not found")
      return
   }
   pids, _ := filepath.Glob(filepath.Join(filepath.Dir(exe), "logs/*.pid"))
   if pids != nil && index == 0 {
      utils.Logf("%s find pid file", filepath.Base(exe))
      if err := Stop(); err == nil {
         //wait for stop done
         for i := 0; i < 10; i++ {
            time.Sleep(1 * time.Second)
            pids, _ := filepath.Glob(filepath.Join(filepath.Dir(exe), "logs/*.pid"))
            if pids == nil {
               log.Printf("%s wait for stop done", filepath.Base(exe))
               break
            }
         }
      }
   }
   //var httpPort int
   //var rtmpPort int
   //if index != 0 {
   // httpPort = int(GetHTTPPort()) + index
   // rtmpPort = int(GetRTMPPort()) + index
   // SetMutliHTTPPort(uint(httpPort), index)
   // SetMutliRTMPPort(uint(rtmpPort), index)
   //}
   if utils.IsPortInUse(int(GetHTTPPort())) && index == 0 {
      err = fmt.Errorf("port[%d] In Use", GetHTTPPort())
      return
   }
   if utils.IsPortInUse(int(GetRTMPPort())) && index == 0 {
      err = fmt.Errorf("port[%d] In Use", GetRTMPPort())
      return
   }
   err = utils.EnsureDir(HLSDir())
   if err != nil {
      log.Println(err)
      return
   }
   err = utils.EnsureDir(RecordDir())
   if err != nil {
      log.Println(err)
      return
   }
   err = utils.EnsureDir(filepath.Join(filepath.Dir(exe), "logs"))
   if err != nil {
      log.Println(err)
      return
   }
   err = utils.EnsureDir(filepath.Join(filepath.Dir(exe), "temp"))
   if err != nil {
      log.Println(err)
      return
   }
   cmd := exec.Command(exe)
   cmd.Dir = filepath.Dir(exe)
   cmd.SysProcAttr = &syscall.SysProcAttr{
      HideWindow:    true,
      CreationFlags: syscall.CREATE_NEW_PROCESS_GROUP,
   }
   err = cmd.Start()
   if err != nil {
      log.Printf("start dss error, %v", err)
      return
   }
   go func() {
      if err := cmd.Wait(); err != nil {
         log.Printf("wait dss error, %v", err)
      }
   }()
   if index == 0 {
      go StartTicker()
   } else {
      go StratMutliTicker(index)
   }
   if index == 0 {
      log.Println("%s start ok, rtmp port[%d], http port[%d]", filepath.Base(exe), GetRTMPPort(), GetHTTPPort())
   } else {
      log.Println("%s start ok, rtmp port[%d], http port[%d]", filepath.Base(exe), GetMutliRTMPPort(index), GetMutliHTTPPort(index))
   }
   return
}

至此,启动多个nginx代码就可以了。但是,现在EasyNVR每个通道还是向默认的nginx进行推流录像,推流直播,因此我们需要在相应的地方进行修改。

func (channel *ChannelInfo) InitPushers(camera *models.Camera) {
   channel.lock.Lock()
   defer channel.lock.Unlock()

   if channel.client == nil {
      return
   }
   rtmpHost := utils.Conf().Section("base_config").Key("rtmp_host").MustString("")
   // 根据配置文件
   enable := utils.Conf().Section("base_config").Key("hls_record_enable").MustBool(true)
   var application = ""
   if enable {
      application = "hls"
   } else {
      application = "record"
   }
   if rtmpHost == "" {
      var rtmpPort uint
      enable := utils.Conf().Section("base_config").Key("multi_nginx_enable").MustBool(false)
      if enable {
         number := utils.Conf().Section("base_config").Key("multi_nginx_number").MustInt()
         channelId := int(channel.Channel)
         index := channelId % number
         rtmpPort = dss.GetMutliRTMPPort(index)
      } else {
         rtmpPort = dss.GetRTMPPort()
      }
      channel.localPusher = stream.NewStreamPusher(fmt.Sprintf("%s - 推流直播", camera.Name), fmt.Sprintf("rtmp://127.0.0.1:%d/%s/%s", rtmpPort, application, StreamID(camera.ID)))
      channel.localPusher.AudioEnable = camera.Reserve1 == "1"
      channel.recordPusher = stream.NewStreamPusher(fmt.Sprintf("%s - 推流录像", camera.Name), fmt.Sprintf("rtmp://127.0.0.1:%d/record/%s", rtmpPort, StreamID(camera.ID)))
      channel.recordPusher.AudioEnable = camera.Reserve1 == "1"
   } else {
      channel.localPusher = stream.NewStreamPusher(fmt.Sprintf("%s - 推流直播", camera.Name), fmt.Sprintf("rtmp://%s/%s/%s", rtmpHost, application, StreamID(camera.ID)))
      channel.localPusher.AudioEnable = camera.Reserve1 == "1"
      channel.recordPusher = stream.NewStreamPusher(fmt.Sprintf("%s - 推流录像", camera.Name), fmt.Sprintf("rtmp://%s/record/%s", rtmpHost, StreamID(camera.ID)))
      channel.recordPusher.AudioEnable = camera.Reserve1 == "1"
   }

经过这样修改后,例如:
EasyNVR配置启动3个nginx,通道1就向nginx1推流,通道2就向nginx2推流,通道3就向nginx3推流,通道4就向nginx1推流…每隔3个通道一次轮回。至此,EasyNVR多nginx方案就已经实现了。

微信图片_20201125161040.png

EasyNVR视频平台被运用在很多场景下,包括智慧水利、智慧交通、校园安防等,当然还有更多的场景在拓展当中,如果大家有需求,欢迎联系我们,TSINGSEE青犀视频团队将根据大家的需求出具最合适的解决方案。

本文地址:https://blog.csdn.net/EasyNVR/article/details/110184766

如您对本文有疑问或者有任何想说的,请点击进行留言回复,万千网友为您解惑!

相关文章:

验证码:
移动技术网