Почему не происходит выполнение кода в горутинах?

Задача проста: небольшой сервер, отвечающий на нескольких портах при подключении некоторые заданные сообщения. Сделал так, чтобы на каждый порт поднималась горутина с листенером.

Код отрабатывает при локальном запуске, но не отрабатывает на удаленном сервере на DO (стартует, пишет приветствие и уходит в цикл, не начиная слушать порты). Пересбор на серверной виртуальной машине с аналогичной версией golang не помогает.

package main

import (
	"fmt"
	"net"
	"os"
	"log"
)

const HOST = "0.0.0.0"

type ServerConfig struct {
	Protocol string
	Port int
	Banner []byte
}

func main() {
	fmt.Println("Server started!")
	var config *ServerConfig
	config = &ServerConfig{
		Protocol:"tcp",
		Port:8001,
		Banner: []byte("Hello!\n")}
	go config.startListener()
	config = &ServerConfig{
		Protocol:"tcp",
		Port:8002,
		Banner: []byte("World\n")}
  go config.startListener()
	for {}
}


func (c *ServerConfig) startListener() error {
	sockAddr :=  HOST+":"+fmt.Sprintf("%v", hc.Port)
	l, err := net.Listen(c.Protocol, sockAddr)
	if err != nil {
		fmt.Println("Error listening:", err.Error())
		//os.Exit(1)
		return err
	}
	defer l.Close()
	fmt.Println("Listening on " + sockAddr)
	for {
		conn, err := l.Accept()
		if err != nil {
			fmt.Println("Error accepting: ", err.Error())
			os.Exit(1)
		}
		// Handle connections in a new goroutine.
		go handleRequest(conn, c.Banner)
	}
}

// Handles incoming requests.
func handleRequest(conn net.Conn, banner []byte) {
	// Make a buffer to hold incoming data.
	conn.Write([]byte(banner))
	buf := make([]byte, 1024)
	// Read the incoming connection into the buffer.
	_, err := conn.Read(buf)
	if err != nil {
		fmt.Println("Error reading:", err.Error())
	}
	// Send a response back to person contacting us.
	conn.Write([]byte(banner))
	// Close the connection when you're done with it.
	conn.Close()
}


В чем может заключаться проблема?
  • Вопрос задан
  • 131 просмотр
Решения вопроса 1
uvelichitel
@uvelichitel Куратор тега Go
habrahabr.ru/users/uvelichitel
Второй листенер запускайте в main, а не в goroutine
config.startListener()  // не нужно go config.startListener()
//обязательно уберите for{}, это плохая конструкция
select{}    //хотя бы так, а если оставить листенер в main треде то и это необязательно
Ответ написан
Пригласить эксперта
Ответы на вопрос 2
@RidgeA
Сколько ядер в DO машине?
Есть предположение, что
for {}
не дает возможности обрабатывать входящие соединения т.к. забивает проц полностью

Вообще, как сказал Andrey Tsvetkov код весьма странный...
Ответ написан
Комментировать
Замените for{} на select{}
У вас в настройках запуска на сервере переменная окружения GOMAXPROС выставлена в 1 скорее всего, поэтому пустой цикл занимает единственный процесс и не даёт остальным горутинам работать. select{} же просто отправит вашу основную горутину в вечный сон без отжирания ресурсов.
Ответ написан
Комментировать
Ваш ответ на вопрос

Войдите, чтобы написать ответ

Похожие вопросы
22 нояб. 2024, в 00:55
500 руб./за проект
21 нояб. 2024, в 23:30
300000 руб./за проект
21 нояб. 2024, в 22:21
3000 руб./в час