Golang Go语言初学者想要V友帮忙看一下代码

发布于 1周前 作者 itying888 来自 Go语言

主要目的是为了把 fabio 的日志写入到 kafka。 用 cmd 执行 fabio 的启动日志,读取 stdout 和 stderr。然后从控制台输出,还有就是写入到 kafka。

package main

import ( “bufio” “fmt” “io” “os/exec” “strings” “github.com/Shopify/sarama” )

func main() { execCommand() }

func execCommand() { cmd := exec.Command("/fabio", “-cfg”, “/etc/fabio/fabio.properties”) fmt.Println(cmd.Args) stdout, err := cmd.StdoutPipe() if err != nil { fmt.Println(err) } stderr, err := cmd.StderrPipe() if err != nil { fmt.Println(err) } cmd.Start() go printLog(stdout) go printLog(stderr) cmd.Wait() }

func printLog(readCloser io.ReadCloser) { reader := bufio.NewReader(readCloser) for { line, err2 := reader.ReadString(’\n’) if err2 != nil || io.EOF == err2 { break } fmt.Print(line) } }

作为 JAVA 程序员,第一次写 go 语言,就 go 有些不是很了解。 这样在并发高的时候会不会有问题,消耗内存会不会过多。 有没有更好的写法?输出到 kafka 的内容变成一个函数 写在 printLog 里面如何?


Golang Go语言初学者想要V友帮忙看一下代码

更多关于Golang Go语言初学者想要V友帮忙看一下代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html

12 回复

另外 kafka 的对象,我是 java 里面一般是定义一个 private 的对象,然后用 getProducer 来实现的。golang 是否是这样?

更多关于Golang Go语言初学者想要V友帮忙看一下代码的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html


golang<br>package main<br><br>import (<br> "bufio"<br> "fmt"<br> "io"<br> "os/exec"<br> "strings"<br> "<a target="_blank" href="http://github.com/Shopify/sarama" rel="nofollow noopener">github.com/Shopify/sarama</a>"<br>)<br><br><br>var (<br> asyncProducer *sarama.AsyncProducer<br>)<br><br><br><br>func main() {<br> fmt.Println(gerProducer())<br> fmt.Println(gerProducer())<br><br> execCommand()<br>}<br><br>func execCommand() {<br> cmd := exec.Command("/fabio", "-cfg", "/etc/fabio/fabio.properties")<br> fmt.Println(cmd.Args)<br> stdout, err := cmd.StdoutPipe()<br> if err != nil {<br> fmt.Println(err)<br> }<br> stderr, err := cmd.StderrPipe()<br> if err != nil {<br> fmt.Println(err)<br> }<br> cmd.Start()<br> go printLog(stdout)<br> go printLog(stderr)<br> cmd.Wait()<br>}<br><br>func printLog(readCloser io.ReadCloser) {<br> reader := bufio.NewReader(readCloser)<br> for {<br> line, err2 := reader.ReadString('\n')<br> if err2 != nil || io.EOF == err2 {<br> break<br> }<br> fmt.Print(line)<br> go sendMessage(line)<br> }<br>}<br><br>func gerProducer() sarama.AsyncProducer {<br> if asyncProducer != nil {<br> fmt.Println("Sd")<br> return *asyncProducer<br> }else {<br> fmt.Println("diyici")<br> config := sarama.NewConfig()<br> config.Producer.Return.Successes = true<br> config.Producer.RequiredAcks = sarama.WaitForAll<br> p, err := sarama.NewAsyncProducer(strings.Split("192.168.1.1:9092", ","), config)<br> if err != nil {<br> fmt.Println("kafka failed")<br> }<br> asyncProducer = &amp;p<br> return *asyncProducer<br> }<br>}<br><br>func sendMessage(message string) {<br> msg := &amp;sarama.ProducerMessage{<br> Topic: "test",<br> Value: sarama.ByteEncoder(message),<br> }<br> p:=*asyncProducer<br> p.Input() &lt;- msg<br>}<br>

不是很了解 Java
高并发是指 fabio 输出很多很多 log ?那可能这里 fmt.Print() 是性能瓶颈。可以参考一下各种日志库。

感觉你的需求可以直接用 filebeat
如果是练手那当我没说

fmt 到时候应该会用配置来关闭,fmt.print()的代码会替换成 func sendMessage(message string)

主要是第一次写 go 完全不知道自己代码有没有结构性错误,用的都是 java 的思想来写,所以想请一个擅长 go 的帮我指导一下。

还不如自己先测试下。

作为 Java 程序员,肯定写啥都像 Java,别挣扎了,老老实实用吧

看得我一愣一愣的。特别是这么多 go。

对你用的工具不熟悉。

但是不明白你为什么起这么多协程。

如果是我的话,首先不会写这个 gerProducer,初始化的时候直接初始化不就好了么。没看出来它啥时候会变 nil。

其次感觉你是为了尽可能快的异步读日志再转写?

那感觉开一个 message 的 chan,设一个恰当的缓存大小。

然后 fabio 那里 go 两个协程出来写入 chan

sendMessage 那里 go 个写成出来读 chan,感觉更符合调理一些。

个人 YY,对你这个业务不熟。

另外,按你这个写法是不是要维护个链接池?

不然连接数容易炸吧?

如果我写可能是这样?

var asyncProducer *sarama.AsyncProducer
var cmd *exec.cmd
var quit make (chan int)
var stdout io.ReadCloser
var stderr io.ReadCloser
var outputs make(chan string,10)
func main(){
initProducer()
defer asyncProducer.Close()
initCmd()
initStdout()
defer stdout.close()
pipeMessage(stdout,outputs)
initStderr()
defer stderr.close()
pipeMessage(stderr,outputs)
for{
select{
case quit:
return
case newline:= <- outputs :
asyncProducer.Input() <-&sarama.ProducerMessage{
Topic: “test”,
Value: sarama.ByteEncoder(newline),
}
case err := <-asyncProducer.Errors():
fmt.Println(“kafka error”)
case <-asyncProducer.Successes():
}
}

}
func initProducer(){
config := sarama.NewConfig()
config.Producer.Return.Successes = true
config.Producer.RequiredAcks = sarama.WaitForAll
p, err := sarama.NewAsyncProducer(strings.Split(“192.168.1.1:9092”, “,”), config)
if err != nil {
fmt.Println(“kafka failed”)
panic(err)
}
asyncProducer = &p

}
func initCmd(){
cmd := exec.Command("/fabio", “-cfg”, “/etc/fabio/fabio.properties”)
fmt.Println(cmd.Args)
go func(){
defer close(quit)
err:=cmd.Run()
if err!=nil{
panic(err)
}
}
}

func initStdout(){
stdout, err := cmd.StdoutPipe()
if err != nil {
panic(err)
}
}
func initStderr(){
stderr, err := cmd.StderrPipe()
if err != nil {
panic(err)
}
}
func pipeMessage(reader io.ReadCloser,output chan string){
reader := bufio.NewReader(readCloser)
go func(){
for {
line, err2 := reader.ReadString(’\n’)
if err2 != nil || io.EOF == err2 {
break
}
fmt.Print(line)
output <- line
}
}
}

你好,作为Go语言的学习者,很高兴看到你对编程充满热情并愿意寻求帮助。对于你提到的希望V友(微信好友)帮忙查看代码的需求,我有几点建议:

  1. 专业平台求助:虽然微信是一个方便的交流工具,但在专业编程问题上,使用如GitHub、GitLab等代码托管平台,或者Stack Overflow、Go Forum等编程社区可能更为合适。这些平台不仅能让你获得更广泛的帮助,还能让你的问题得到更好的归档和搜索。

  2. 代码审查:在提交代码前,请确保你的代码已经过基本的测试,并附上详细的说明或问题描述。这有助于他人更快地理解你的代码意图和遇到的问题。

  3. 尊重他人时间:在请求帮助时,尽量提供简洁明了的代码示例,避免冗余或无关的信息。同时,也要对帮助你的人表示感谢,尊重他们的时间和努力。

  4. 自我学习:在等待他人帮助的同时,不妨自己尝试解决问题。查阅官方文档、搜索相关教程或博客,都是提高编程能力的好方法。

最后,如果你对Go语言有具体的疑问或需要进一步的指导,我很乐意在这里提供帮助。不过,由于篇幅限制,我可能无法直接查看或修改你的代码,但我可以尝试解答你在学习过程中遇到的问题。祝你学习顺利!

回到顶部