Golang 实现UDPServer并发送消息到ActiveMQ
示例代码
package main import (
"net"
"os"
"github.com/gpmgo/gopm/modules/goconfig"
"github.com/go-stomp/stomp"
"time"
"strconv"
"log"
"strings"
) // 限制goroutine数量
var limitChan = make(chan bool, ) // Todo 从配置文件中读取 // 限制同时处理消息数量
var msgChan = make(chan string, ) // Todo 从配置文件中读取
var activeMqLimitedChan = make(chan bool, )
var activeMq *stomp.Conn
var activeQueue string
var host string
var port string
var connectTimes =
var udpAddress = "0.0.0.0" // Todo 从配置文件中读取
var udpPort = "" // Todo 从配置文件中读取
var logFilePath = "/var/log/syslog_server/"
var configFilePath = "./config.ini"
// UDP goroutine 实现并发读取UDP数据
func udpProcess(conn *net.UDPConn) {
defer func() {
if e := recover(); e != nil {
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error())
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("udpProcess error:", e)
}
// 释放出一个协程
<- limitChan
}() // 最大读取数据大小
data := make([]byte, )
n, _, err := conn.ReadFromUDP(data)
if err != nil {
panic(err)
} // 获取对端的IP地址
// remoteAddr := conn.RemoteAddr()
// msgChan <- remoteAddr.String() + " " + string(data[:n]) msgChan <- string(data[:n]) } func udpServer(address, port string) {
// @todo 如何防止udpServer 一直Panic导致无限循环重启
defer func() {
if e := recover(); e != nil {
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error())
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("udpServer error:", e) // udpServer启动失败后,间隔10秒后重试
time.Sleep( * time.Second)
udpServer(udpAddress, udpPort)
}
}() udpAddr, err := net.ResolveUDPAddr("udp", net.JoinHostPort(address, port))
conn, err := net.ListenUDP("udp", udpAddr)
defer conn.Close()
if err != nil {
panic(err)
} for {
limitChan <- true
go udpProcess(conn)
}
} // 读取ActiveMQ配置信息
func getConfiguration(){
defer func() {
if e := recover(); e != nil {
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error(), ", programing exit.")
os.Exit()
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("Get Configuration error:", e)
}
}() configFile, err := goconfig.LoadConfigFile(configFilePath)
if err != nil {
panic(err)
} host, err = configFile.GetValue("active_mq", "host")
if err != nil {
// 如果没有配置主机,则使用本地主机
host = "127.0.0.1"
}
port, err = configFile.GetValue("active_mq", "port")
if err != nil {
// 如果没配置端口,则使用默认端口
port = ""
} activeQueue, err = configFile.GetValue("active_mq", "queue")
if err != nil {
// 如果没配置端口,则使用默认队列名
activeQueue = "syslog.queue"
}
} // 使用IP和端口连接到ActiveMQ服务器, 返回ActiveMQ连接对象
func connActiveMq(){
// @todo 如何防止无限循环
defer func() {
if e := recover(); e != nil {
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error())
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("connActiveMq error:", e) // ActiveMQ服务器连接失败后,间隔3秒后重试
time.Sleep( * time.Second)
activeMq = nil
connActiveMq()
}
}() // @todo 实现断开重连
if activeMq == nil {
var err error
activeMq, err = stomp.Dial("tcp", net.JoinHostPort(host, port))
if err != nil {
connectTimes ++
if connectTimes >= {
time.Sleep( * time.Second)
}else if connectTimes >= {
time.Sleep( * time.Second)
}else {
time.Sleep( * time.Second)
}
panic(err.Error() + ", 重新连接ActiveMQ, 已重试次数: " + strconv.Itoa(connectTimes)) }else {
connectTimes =
}
}
} func activeMqProducer(c chan string){
// @todo 如何防止activeMqProducer 退出
defer func() {
if e := recover(); e != nil {
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error())
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("activeMqProducer error:", e) // 重试
go activeMqProducer(msgChan)
}
}()
for{
activeMqLimitedChan <- true // 限制开启协程数量
contentMsg := <-c
go func() {
defer func() {
if e := recover(); e != nil {
err := os.MkdirAll(logFilePath, )
log.Fatalln("create log dirctory error: ", err.Error())
// 初始化日志,每天生成一个日志文件,日志文件名以日志结尾
logFileName := logFilePath + "server-" + strings.Split(time.Now().String(), " ")[] + ".log"
logFile, err := os.OpenFile(logFileName, os.O_RDWR|os.O_CREATE|os.O_APPEND, ) // 应该判断error,此处简略
defer logFile.Close()
if err != nil {
log.Fatalln("open log file error: ", err.Error())
}
logger := log.New(logFile, "[Error] ", log.Ldate|log.Ltime|log.Lshortfile) // 记录错误日志
logger.Println("activeMqProducer error:", e)
}
// 释放出一个协程
<- activeMqLimitedChan
}() err := activeMq.Send(activeQueue, "text/plain", []byte(contentMsg))
if err != nil {
if err.Error() == "connection already closed"{
activeMq = nil
connActiveMq()
activeMq.Send(activeQueue, "text/plain", []byte(contentMsg))
}
panic(err)
}
}() } } func init(){
// 初始化 ActiveMQ 配置
getConfiguration() // 连接到 ActiveMQ 服务器
connActiveMq() // 启动一个协程将Syslog消息放入ActiveMQ队列中
go activeMqProducer(msgChan) } func main() {
defer activeMq.Disconnect()
udpServer(udpAddress, udpPort)
}
Golang 实现UDPServer并发送消息到ActiveMQ的更多相关文章
- java 消息机制 ActiveMQ入门实例
1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ 我下载的时候是 ActiveMQ 5.14.0 Release版 2.运行ActiveMQ 解压缩ap ...
- Java消息机制 ActiveMQ入门实例
转载自:http://www.cnblogs.com/wyh3721/p/5917316.html 1.下载ActiveMQ 去官方网站下载:http://activemq.apache.org/ ...
- java之消息队列ActiveMQ实践
原创论文:https://www.cnblogs.com/goujh/p/8510239.html 消息队列的应用场景: 消息队列应用场景 异步处理,应用解耦,流量削锋和消息通讯四个场景 异步处理: ...
- Golang之发送消息至kafka
windows下安装zookeeper 1.安装JAVA-JDK,从oracle下载最新的SDK安装(我用的是1.8的) 2.安装zookeeper3.3.6,下载地址:http://apache.f ...
- ActiveMQ producer不断发送消息,会导致broker内存耗尽吗?
http://activemq.apache.org/my-producer-blocks.html 回答了这个问题: ActiveMQ 5.x 支持Message Cursors,它默认把消息从内存 ...
- ActiveMQ producer同步/异步发送消息
http://activemq.apache.org/async-sends.html producer发送消息有同步和异步两种模式,可以通过代码配置: ((ActiveMQConnection)co ...
- php 事务处理,ActiveMQ的发送消息,与处理消息
可以通过链式发送->处理->发送...的方式处理类似事务型业务逻辑 比如 发送一个注册消息,消息队列处理完注册以后,紧接着发送一个新手优惠券赠送,赠送完再发一个其它后续逻辑处理的消息等待后 ...
- 【Java Web开发学习】Spring消息-ActiveMQ发送消息
ActiveMQ发送消息 转载:http://www.cnblogs.com/yangchongxing/p/9042401.html Java消息服务(Java Message Service, J ...
- activeMq发送消息流程
1,发送消息入口 Message message = messageBean.getMessageCreator().createMessage(session); producer.send(mes ...
随机推荐
- 线性排序总结(c++实现)
前面介绍了一些常用的比较排序算法,它们都是通过比较两个元素的大小进行排序,归并排序和堆排序在最坏情况下的复杂度为O(nlgn),可以证明(使用决策树模型),通过比较进行排序,算法的下界为O(nlgn) ...
- DT系统开发之-在线询盘信息的调取实现
调用标签 <!--{tag("table=message&condition=status=3 and typeid=1&areaid=$cityid&cati ...
- MongoDB 部署复制集(副本集)
部署MongoDB复制集(副本集) 环境 操作系统:Ubuntu 18.04 MongoDB: 4.0.3 服务器 首先部署3台服务器,1台主节点 + 2台从节点 3台服务器的内容ip分别是: 1 ...
- 通过日志解决问题的一个小例子-http换端口
这个例子是将http服务的监听端口改为8999后重启服务报错: 此时查看日志/var/log/message,显示如下: 如红笔所示轨迹得到设置端口类型的命令:semanage port -a -t ...
- 部署django到服务器
部署 服务器环境配置 在本地的虚拟环境中,项目根目录下,执行命令收集所有的包 pip freeze > plist.txt 安装并创建虚拟环境,如已创建则跳过此步 sudo apt-get in ...
- javascript冒泡排序 至少比较N(N-1)/2次;
<script type="text/javascript"> function get(){ var num = [10,5,2,1,3,6,4,7,9,8]; va ...
- 同余方程组(EXCRT)(luogu4777)
#include<cstdio> #include<algorithm> #define ll long long using namespace std; ll k; ll ...
- A_G_C_007
AGC007 A Shik and Stone 我是沙比这都能蛙一发 https://agc007.contest.atcoder.jp/submissions/7946110 B Construct ...
- Shared Virtual Memory (SVM) Functions
Description Shared Virtual Memory (SVM) (Glossary): An address space exposed to both the host and th ...
- windows自动修复失败,无法启动
Windows10操作系统于2015年7月29日正式发布,此后,win10也就成了新上市的笔记本电脑或者台式机电脑的预装操作系统!win10系统给我们带了全新的体验,当然也带来了一定的烦恼!就拿win ...