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 ...
随机推荐
- 设计模式--Proxy模式
这篇主要介绍代理模式相关内容,主要是一些基本概念普及. 代理模式 1.什么是代理模式? 代理模式(Proxy),为其他对象提供一种代理以控制对这个对象的访问.[DP] 通俗的说就是指客户端并不直接调用 ...
- Vcode的生成工具类,生成制定长度验证码,图文验证码工具类
public class VCodeUtils { // 使用到Algerian字体,系统里没有的话需要安装字体,字体只显示大写,去掉了1,0,i,o几个容易混淆的字符 public static f ...
- SSM之JSON通用返回格式
/** * 通用的返回的类 * */ public class Result { //状态码 100-成功 200-失败 private int code; //提示信息 private String ...
- 软件测试之Monkey 初步了解(入门级II)
1. 先熟悉monkey基本命令: cls 清除 首先测试设备是否连接成功,在命令行中输入:adb devices 查看adb版本: adb version 查看虚拟机版本:nox_adb ver ...
- [教程]Ubuntu16.04安装TeX Live
[教程]Ubuntu16.04安装TeX Live step 1 戳这里下载镜像 (只需要下载texlive.iso) 在终端输入 sudo apt-get install perl-tk step ...
- linux学习15 Linux系统用户和组全面讲解
一.用户,组和权限管理 1.多用户(Multi-tasks),多任务(Multi-Users).对计算机而言,每一个使用者就是一个用户. 2.每个使用者: a.用户标识,密码: 认证(Authenti ...
- systemd socket activation golang demo
service define rongapp.service [Unit] Description=rong Hello World HTTP Requires=network.target rong ...
- haproxy2.0 dataplaneapi 简单说明
haproxy2.0 支持基于dataplaneapi 的haproxy 动态配置修改以及服务生效,早期大家为了动态 可以会基于dsn 的服务发现模式,基于confd 结合consul 动态生成配置并 ...
- github Actions 使用方法
http://www.ruanyifeng.com/blog/2019/09/getting-started-with-github-actions.html Actions 是github提供的持续 ...
- ACM数据结构-树状数组
模板: int n; int tree[LEN]; int lowbit(int x){ return x&-x; } void update(int i,int d){//index,del ...