Open23
ISUCON Snippets
sqlx関連
func sqlxIn[P any](resp any, query string, args []P) error {
if len(args) == 0 {
return nil
}
query, params, err := sqlx.In(query, args)
if err != nil {
return err
}
return db.Select(resp, query, params...)
}
Bulk INSERT
if len(userPresents) > 0 {
query := `INSERT INTO user_presents(id, user_id, sent_at, item_type, item_id, amount, present_message, created_at, updated_at)
VALUES (:id, :user_id, :sent_at, :item_type, :item_id, :amount, :present_message, :created_at, :updated_at)`
if _, err := tx.NamedExec(query, userPresents); err != nil {
return nil, err
}
}
Bulk IODKUの例
if len(insertUserItems) > 0 {
query := `INSERT INTO user_items(id, user_id, item_id, item_type, amount, created_at, updated_at)
VALUES (:id, :user_id, :item_id, :item_type, :amount, :created_at, :updated_at)
ON DUPLICATE KEY UPDATE amount=VALUES(amount), updated_at=VALUES(updated_at)`
if _, err := tx.NamedExec(query, insertUserItems); err != nil {
return err
}
}
Kataribe
MySQL
Goのpprof
Go GlobalCache
type GlobalCache[K comparable, V any] struct {
value map[K]V
*sync.Mutex
}
func NewGlobalCache[K comparable, V any]() *GlobalCache[K, V] {
return &GlobalCache[K, V]{
value: make(map[K]V),
Mutex: &sync.Mutex{},
}
}
func (c *GlobalCache[K, V]) Load(key K) (V, bool) {
c.Lock()
defer c.Unlock()
v, ok := c.value[key]
return v, ok
}
func (c *GlobalCache[K, V]) Store(key K, value V) {
c.Lock()
defer c.Unlock()
c.value[key] = value
}
func (c *GlobalCache[K, V]) Delete(key K) {
c.Lock()
defer c.Unlock()
delete(c.value, key)
}
func (c *GlobalCache[K, V]) Clear() {
c.Lock()
defer c.Unlock()
c.value = make(map[K]V)
}
func (c *GlobalCache[K, V]) Keys() []K {
c.Lock()
defer c.Unlock()
keys := make([]K, 0, len(c.value))
for k := range c.value {
keys = append(keys, k)
}
return keys
}
var (
bannedUsers = NewGlobalCache[int64, bool]()
)
Makefile
upload-mysql:
sudo cp ./conf/mysql.cnf /etc/mysql/mysql.conf.d/
restart-mysql:
sudo systemctl restart mysql
deploy-mysql: upload-mysql restart-mysql truncate-mysql-log
upload-nginx:
sudo cp ./conf/nginx.conf /etc/nginx/
restart-nginx:
sudo systemctl reload nginx
deploy-nginx: upload-nginx restart-nginx truncate-nginx-log
build-go:
cd webapp/golang && \
go build -o app
restart-go:
sudo systemctl restart isu-go
deploy-go: build-go restart-go truncate-go-log
deploy: deploy-mysql deploy-nginx deploy-go
collect-nginx-log:
sudo cat /var/log/nginx/access.log | ~/go/bin/kataribe > "logs/nginx-$(shell date +'%Y%m%d%H%M%S').log"
sudo cat /var/log/nginx/error.log > "logs/nginx-error.log"
collect-mysql-log:
sudo pt-query-digest /var/log/mysql/mysql-slow.log > "logs/mysql-$(shell date +'%Y%m%d%H%M%S').log"
collect-go-log:
sudo journalctl -u isu-go > "logs/go-app.log"
logs: collect-nginx-log collect-mysql-log collect-go-log
truncate-nginx-log:
sudo truncate -s 0 /var/log/nginx/access.log
sudo truncate -s 0 /var/log/nginx/error.log
truncate-mysql-log:
sudo truncate -s 0 /var/log/mysql/mysql-slow.log
truncate-go-log:
sudo journalctl --vacuum-time=1s