Socket Types
- Stream Socket SOCK_STREAM 串流式
- Datagram Socket SOCK_DGRAM 訊息式
- Row Socket
- Link Layer Socket
基於TCP
資料需要可靠的、需要順序的多半用stream socket
例如:HTTP/TELNET
基於UDP
不可靠、不一定照順序、但是如果送達(封包重組完成,如果有分割的話),資料就是正確的。
遊戲玩家位置、音樂、音效,等可容許小量丟失的。
例如:TFT/DHCPD
TCP connection -> connection -> channel
Producer -> exchange -> Queue -> exchange -> Consumer Queue -> exchange -> Consumer
輪流派送給每個註冊的worker
msgs, err := ch.Consume( q.Name, // queue "", // consumer false, // auto-ack false, // exclusive false, // no-local false, // no-wait nil, // args ) //幾本上auto-ack都要設成true,不然就要自己送 //否則rabbitmq 會保留此message,造成資源消耗 go func() { for d := range msgs { log.Printf("Received a message: %s", d.Body) dot_count := bytes.Count(d.Body, []byte(".")) t := time.Duration(dot_count) time.Sleep(t * time.Second) log.Printf("Done") d.Ack(false) } }()
q, err := ch.QueueDeclare( "hello", // name true, // durable false, // delete when unused false, // exclusive false, // no-wait nil, // arguments ) //producer、consumer宣告的queue durable要設成true //宣告同名的queue參數必須相同,否則錯誤 err = ch.Publish( "", // exchange q.Name, // routing key false, // mandatory false, amqp.Publishing { DeliveryMode: amqp.Persistent, ContentType: "text/plain", Body: []byte(body), }) //publishing DeliveryMode 要設成 amqp.Persistent
基本上RabbitMQ的派送是平均派送,當他收到就派送, 所以有可能派送給還沒完成工作的worker。 可設定prefetch count=1 這時rabbitMQ會收到前一個message的acknowledgement才會派送下一個。 注意,此時queue有可能被填滿,你需要多設定幾個woker。 err = ch.Qos( 1, // prefetch count 0, // prefetch size false, // global )
4 types of exchange:direct,topic,headers,fanout err = ch.ExchangeDeclare( "logs", // name "fanout", // type true, // durable false, // auto-deleted false, // internal false, // no-wait nil, // arguments ) //fanout:broadcast all messages to all the queues it knows
err = ch.QueueBind( q.Name, // queue name "", // routing key "logs", // exchange false, nil )
exchange publish時,可以加上路由(routing key) queue可以綁定exchange及routing key 一個queue可以綁定一個exchange及多個routing key 這樣就可以一個exchange 用多種routing發布,然後consumer利用不同routing接收
//Binding 是綁定exchange 及 queue //Binding時可以設定路由,用routing key parameter err = ch.QueueBind( q.Name, // queue name "black", // routing key "logs", // exchange false, nil) //route to black
//用direct exchange才能使用binding的routing key //用fanout exchange會忽略routing key參數,合理,所以他才叫fanout err = ch.ExchangeDeclare( "logs_direct", // name "direct", // type true, // durable false, // auto-deleted false, // internal false, // no-wait nil, // arguments ) q, err := ch.QueueDeclare( "", // name false, // durable false, // delete when usused true, // exclusive false, // no-wait nil, // arguments ) err = ch.QueueBind( q.Name, // queue name "", // routing key "logs", // exchange false, nil )
4 types of exchange:direct,topic,headers,fanout err = ch.ExchangeDeclare( "logs", // name "fanout", // type true, // durable false, // auto-deleted false, // internal false, // no-wait nil, // arguments ) //fanout:broadcast all messages to all the queues it knows
err = ch.QueueBind( q.Name, // queue name "", // routing key "logs", // exchange false, nil )
systemctl start rabbitmq-server
相關的scripts及cli tools安裝在/usr/local/opt/rabbitmq/sbin,
需要自己加到path
export PATH=$PATH:/usr/local/opt/rabbitmq/sbin
brew services start rabbitmq brew services stoprabbitmq啟動在前景
/usr/local/Cellar/rabbitmq/3.7.11/sbin/rabbitmq-server
rabbitmqctl add_user admin admin更改使用者tag,改成管理者 set_user_tags
rabbitmqctl set_user_tags admin administrator更改使用者權限 set_permissions [name]
rabbitmqctl set_permissions -p / username ".*" ".*" ".*"更改密碼 change_password [username] [password]
rabbitmqctl change_password admin admin查詢未確認的message(unacknowledged) list_queues [queueName] messages_ready messages_unacknowledged
sudo rabbitmqctl list_queues queueName messages_ready messages_unacknowledged
rabbitmq-plugins enable rabbitmq-management
rabbitmq-plugins [-n [node]] [-t [timeout]] [-l] [-q] [command] [command options] Eg. rabbitmq-plugins [-n] [-t ] [-l] [-q] is_enabled [plugin1] [plugin2]
-n node -q quiet -h help list 列出所有外掛 is_enabled [plugin1][,[plugin2]] 查看plugin是否啟用 enable [plugin] 啟用外掛
rabbitmq-plugins enable rabbitmq_management
-t 指定repository:tag docker build . -t repository:tag eg: docker build . it myname/golang:1.14-centos7 -f 指定dockerfile docker build -f dockerfile.debug build with RUL docker build github.com/create/docker-firefox
--interactive,-i Keep STDIN open even if not attached --tty,-t Allocate a pseudo-TTY --ulimit Ulimit options --mount Attach a filesystem mount to the container --add-host Add a custom host-to-IP mapping(host:ip) --attach,-a Attach to STDIN,STDOUT or STDERR --link Add link to another container --name Assign a name to the container --publish,-p Publish a container's port(s) to the host --publish-all, -P Publish all exposed ports to random ports --expose expose a port --rm Automatically remove the container when it exits --ip IPv4 Address --ip6 IPv6 address -w lets the container command being executed inside directory given
$ docker run --name test -it debianSet working directory
$ docker run -w /path/to/dir/ -i -t ubuntu pwdExporse port 80 of the container without publishing the port to host
$ docker run --expose 80 ubuntu bashPublish a port
$ docker run -p 127.0.0.1:80:8080/tcp ubuntu bash