golang 初始化Redis的连接池

redisInit.go

//调用Redis前必须初始化该方法
func Init(service string) {
	// 获取全部redis address
	hosts, err := utils.AllBns(service)
	if err != nil {
		log.Warn("get_redis_host_by_bns_fail: ", err)
		return
	}
	log.Debug("redis_hosts: ", hosts)
	// 写入配置及对应的连接池,添加到slice中
	redises := make([]internalRedis, len(hosts))
	for idx, host := range hosts {
		conf := RedisConfig{
			HostPort:    host,
			MaxIdle:     25,
			MaxActive:   25,
			IdleTimeout: 2400,
			Passwd:      "",
			Database:    0,
			Timeout:     5,
		}
		redises[idx] = internalRedis{
			config: conf,
			pool:   getPool(conf),
		}
	}
	//5.写入全局变量并获取连接池
	serviceMap[service] = Redis{
		Service:         service,
		internalRedises: redises,
	}
}

func getPool(conf RedisConfig) *redis.Pool {
	return &redis.Pool{
		MaxIdle:     conf.MaxIdle,
		MaxActive:   conf.MaxActive,
		IdleTimeout: conf.IdleTimeout * time.Second,
		Wait:        true,
		Dial: func() (conn redis.Conn, e error) {
			con, err := redis.Dial("tcp", conf.HostPort,
				redis.DialPassword(conf.Passwd),
				redis.DialDatabase(conf.Database),
				redis.DialConnectTimeout(conf.Timeout*time.Second),
				redis.DialReadTimeout(conf.Timeout*time.Second),
				redis.DialWriteTimeout(conf.Timeout*time.Second),
			)

			if err != nil {
				log.Warn("get_redis_conn_fail: ", err)
				return nil, err
			}
			return con, nil
		},
		TestOnBorrow: func(c redis.Conn, t time.Time) error {
			if time.Since(t) < time.Minute {
				return nil
			}
			_, err := c.Do("PING")
			return err
		},
	}
}

// 获取连接
func (objRedis *Redis) getConn() (redis.Conn, error) {
	defer func() {
		if err := recover(); err != nil {
			log.Panicf("Redis getConn err : %s", err)
		}
	}()
	redises := objRedis.internalRedises
	redisesLen := uint64(len(redises))
	if redisesLen == 0 {
		return nil, errors.New("Invalid redis host list")
	}

	tryCount := 0
	for tryCount < 3 {
		tryCount++
		indexIncr := atomic.AddUint64(&redisRoundRobinCurrent, 1)
		index := indexIncr % redisesLen
		redisConn := redises[index]
		conn := redisConn.getConn()
		if _, err := conn.Do("ping"); err != nil {
			log.Warn("redis host conn fail: ", redisConn.config)
			conn.Close()
			continue
		}
		return conn, nil
	}
	return nil, errors.New("cache conn fail")
}

// 获取连接
func (redis *internalRedis) getConn() redis.Conn {
	conn := redis.pool.Get()
	return conn
}

golang TheCallOutToThings

TheCallOutToThings

TheCountingRecursionOfThings.go
func main() {

	htmlContent, err := ioutil.ReadFile("compositecode.html")
	if err != nil {
		fmt.Println(err)
	}

	htmlData := string(htmlContent)
	r := strings.NewReader(htmlData)

	doc, err := html.Parse(r)
	if err != nil {
		fmt.Fprintf(os.Stderr, "find links: %v\n", err)
		os.Exit(1)
	}
	for _, link := range visit(nil, doc) {
		fmt.Println(link)
	}

	w, i, _ := CountWordsAndImages("https://compositecode.blog")
	fmt.Printf("Words: %d\nImages: %d\n", w, i)
}

golang TheCountOfWordsAndImages

TheCountOfWordsAndImages

counting.go
func CountWordsAndImages(url string) (words, images int, err error) {
	resp, err := http.Get(url)

	if err != nil {
		return
	}

	doc, err := html.Parse(resp.Body)
	resp.Body.Close()
	if err != nil {
		err = fmt.Errorf("parsing HTML: %s", err)
	}
	words, images = countWordsAndImages(doc)
	return
}

func countWordsAndImages(n *html.Node) (words, images int) {
	if n.Type == html.TextNode {
		words += len(strings.Split(n.Data, " "))
		return
	}

	if n.Data == "img" {
		images++
	} else {
		if n.FirstChild != nil {
			w, i := countWordsAndImages(n.FirstChild)
			words += w
			images += i
		}
		if n.NextSibling != nil {
			w, i := countWordsAndImages(n.NextSibling)
			words += w
			images += i
		}
	}
	return
}

golang 访问功能。

访问功能。

visit_func.go
func visit(links []string, n *html.Node) []string {
	if n.Type == html.ElementNode && n.Data == "a" {
		for _, a := range n.Attr {
			if a.Key == "href" {
				links = append(links, a.Val)
			}
		}
	}
	for c := n.FirstChild; c != nil; c = c.NextSibling {
		links = visit(links, c)
	}
	return links
}

golang 用于解析HTML的类型,节点,常量等设置。

用于解析HTML的类型,节点,常量等设置。

types_nodes_etc.go
type NodeType int32

const (
	ErrorNode NodeType = iota
	TextNode
	DocumentNode
	ElementNode
	Commentnode
	DoctypeNode
)

type Node struct {
	Type                    NodeType
	Data                    string
	Attr                    []Attribute
	FirstChild, NextSibling *Node
}

type Attribute struct {
	Key, Val string
}

golang 从func main调用的示例函数。

从func main调用的示例函数。

func_main_plus_example_executor.go
package main

import "fmt"

func main() {

	var this, result int
	var that, message string
	this = 2
	that = "42"

	result, message = exampleExecutor(this, that)

	fmt.Printf("%s\n%d", message, result)
}

func exampleExecutor(this int, that string) (int, string) {

	fmt.Printf("Numbers: %d, %s\n", this, that)

	return this, "This is the result: " + that
}

golang 使用命名参数不当

fun_return_named_var.go
package main

import (
	"errors"
	"fmt"
	"math/rand"
	"time"
)

var (
	errA = errors.New("a")
	errB = errors.New("b")
	errC = errors.New("c")
)

func theFun() error {
	return errC
}

func foobar() (err error) {

	err = theFun()
	if err == errA || err == errB {
		return
	}

	r := rand.New(rand.NewSource(time.Now().UnixNano()))
	x := r.Intn(10)
	y := r.Intn(10)

	if x > y {
		return errors.New("x>y found, bad")
	}
	return
}

func main() {

	fmt.Println(foobar())
}

golang 循环中不用加函数调用

循环中不要加函数调用

loop_funcation_call.go
package main

import (
	"fmt"
)

type Obj struct {
	names []string
}

func (o Obj) len() int {
	fmt.Println("DEBUG1")
	return len(o.names)
}

func main() {
	o := Obj{
		names: []string{
			"a",
			"b",
			"c",
		},
	}
	for i := 0; i < o.len(); i++ {
		fmt.Println(o.names[i])
	}
}
for_range_with_fun_call.go
package main

import "fmt"

func foobar() []int {
	fmt.Println("DEUBG")
	return []int{1, 2, 3}
}

func main() {
	for _, i := range foobar() {
		fmt.Println(i)
	}

}
// 在range循环里面是没有问题的

golang 版权声明

copyright.go
/*
Copyright 2014 The LABCHAN Authors.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
    http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/

golang [结构和类型]达美

client-go_tools_cache_delta_fifo.go
type Delta struct {
    Type   DeltaType
    Object interface{}
}

type DeltaType string
const ( 
    Added   DeltaType = "Added"
    Updated DeltaType = "Updated"
    Deleted DeltaType = "Deleted"
    Sync DeltaType = "Sync"
)