Skip to content

Commit

Permalink
Merge pull request #106 from yoyofx/dev
Browse files Browse the repository at this point in the history
1.5.9
  • Loading branch information
yoyofx authored Dec 8, 2020
2 parents 7b0a9a1 + 516f69e commit 4f6206c
Show file tree
Hide file tree
Showing 15 changed files with 452 additions and 9 deletions.
8 changes: 8 additions & 0 deletions Abstractions/IDataSource.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
package Abstractions

type IDataSource interface {
GetName() string
Open() (conn interface{}, put func(), err error)
Close()
Ping() bool
}
2 changes: 2 additions & 0 deletions Abstractions/Pool/Pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -18,4 +18,6 @@ type Pool interface {
Release()

Len() int

Ping(interface{}) error
}
10 changes: 10 additions & 0 deletions DependencyInjection/ServiceCollection.go
Original file line number Diff line number Diff line change
Expand Up @@ -35,11 +35,21 @@ func (sc *ServiceCollection) AddSingleton(provider interface{}) {
sc.AddServiceDescriptor(sd)
}

func (sc *ServiceCollection) AddSingletonAndName(name string, provider interface{}) {
sc.AddSingletonByName(name, provider)
sc.AddSingleton(provider)
}

func (sc *ServiceCollection) AddSingletonByName(name string, provider interface{}) {
sd := NewServiceDescriptorByName(name, provider, Singleton)
sc.AddServiceDescriptor(sd)
}

func (sc *ServiceCollection) AddSingletonByImplementsAndName(name string, provider interface{}, implements interface{}) {
sc.AddSingletonByName(name, provider)
sc.AddSingletonByImplements(provider, implements)
}

func (sc *ServiceCollection) AddSingletonByImplements(provider interface{}, implements interface{}) {
sd := NewServiceDescriptorByImplements(provider, implements, Singleton)
sc.AddServiceDescriptor(sd)
Expand Down
20 changes: 20 additions & 0 deletions Examples/SimpleWeb/config_dev.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,23 @@ yoyogo:
# type: "eureka"
# metadata:
# address: "http://localhost:5000/eureka"
datasource:
mysql:
name: db1
url: tcp(cdb-amqub3mo.bj.tencentcdb.com:10042)/yoyoBlog?charset=utf8&parseTime=True
username: root
password: 1234abcd
debug: true
pool:
init_cap: 2
max_cap: 5
idle_timeout : 5
redis:
name: reids1
url: 127.0.0.1:6379
password:
db: 0
pool:
init_cap: 2
max_cap: 5
idle_timeout: 5
9 changes: 5 additions & 4 deletions Examples/SimpleWeb/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,11 @@ module SimpleWeb

go 1.15

require github.com/yoyofx/yoyogo v0.0.0

replace (
github.com/yoyofx/yoyogo => ../../
require (
github.com/go-sql-driver/mysql v1.5.0
github.com/yoyofx/yoyogo v0.0.0
)

replace github.com/yoyofx/yoyogo => ../../

//require github.com/yoyofx/yoyogo v1.5.5
7 changes: 7 additions & 0 deletions Examples/SimpleWeb/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,10 +4,12 @@ import (
"SimpleWeb/contollers"
"SimpleWeb/models"
"fmt"
_ "github.com/go-sql-driver/mysql"
"github.com/yoyofx/yoyogo/Abstractions"
"github.com/yoyofx/yoyogo/Abstractions/XLog"
"github.com/yoyofx/yoyogo/DependencyInjection"
"github.com/yoyofx/yoyogo/Internal/ServiceDiscoveryProvider/Nacos"
"github.com/yoyofx/yoyogo/Internal/datasources"
"github.com/yoyofx/yoyogo/WebFramework"
"github.com/yoyofx/yoyogo/WebFramework/Context"
"github.com/yoyofx/yoyogo/WebFramework/Endpoints"
Expand Down Expand Up @@ -56,6 +58,9 @@ func CreateCustomBuilder() *Abstractions.HostBuilder {
}).
ConfigureServices(func(serviceCollection *DependencyInjection.ServiceCollection) {
serviceCollection.AddTransientByImplements(models.NewUserAction, new(models.IUserAction))
serviceCollection.AddSingletonByImplementsAndName("db1", datasources.NewMysqlDataSource, new(Abstractions.IDataSource))
serviceCollection.AddSingletonByImplementsAndName("redis1", datasources.NewRedis, new(Abstractions.IDataSource))

// Eureka.UseServiceDiscovery(serviceCollection)
//Consul.UseServiceDiscovery(serviceCollection)
Nacos.UseServiceDiscovery(serviceCollection)
Expand All @@ -71,6 +76,8 @@ func registerEndpointRouterConfig(router Router.IRouterBuilder) {
Endpoints.UseViz(router)
Endpoints.UsePrometheus(router)
Endpoints.UsePprof(router)
Endpoints.UseReadiness(router)
Endpoints.UseLiveness(router)
//Endpoints.UseJwt(router)

router.GET("/error", func(ctx *Context.HttpContext) {
Expand Down
11 changes: 8 additions & 3 deletions Examples/SimpleWeb/scripts/k8s-deploy.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
apiVersion: apps/v1
kind: Deployment
metadata:
namespace: default
name: yoyogodemo
spec:
selector:
Expand All @@ -10,13 +11,17 @@ spec:
replicas: 1 # tells deployment to run 2 pods matching the template
template: # create pods using pod definition in this template
metadata:
annotations:
prometheus.io/path: /app/actuator/metrics
prometheus.io/port: "8080"
prometheus.io/scrape: "true"
labels:
app: yoyogodemo
spec:
containers:
- name: yoyogodemo
image: maxzhang1985/yoyogo:version-1.4.6
imagePullPolicy: Always #Always 总是拉取镜像 IfNotPresent 本地有则使用本地镜像,不拉取Never 只使用本地镜像,从不拉取,即使本地没有
image: ccr.ccs.tencentyun.com/tsf_86509022/yoyogo_demo:dev-2090a2b9f9d618da306bc079422f264abc421f60
imagePullPolicy: IfNotPresent #Always 总是拉取镜像 IfNotPresent 本地有则使用本地镜像,不拉取Never 只使用本地镜像,从不拉取,即使本地没有
ports:
- containerPort: 8080
livenessProbe:
Expand All @@ -26,5 +31,5 @@ spec:
initialDelaySeconds: 15
timeoutSeconds: 1
env:
- name: PROFILE
- name: TEST
value: "test12"
153 changes: 153 additions & 0 deletions Internal/datasources/mysql.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,153 @@
package datasources

import (
"database/sql"
"errors"
"fmt"
"github.com/yoyofx/yoyogo/Abstractions"
"github.com/yoyofx/yoyogo/Abstractions/Pool"
"github.com/yoyofx/yoyogo/Abstractions/XLog"
"sync"
"time"
)

// DataSourceConfig 数据源配置
type dataSourceConfig struct {
Name string `mapstructure:"name"`
Url string `mapstructure:"url"`
UserName string `mapstructure:"username"`
Password string `mapstructure:"password"`
Debug bool `mapstructure:"debug"`
Pool *dataSourcePool `mapstructure:"pool"`
}

// DataSourcePool 数据源连接池配置
type dataSourcePool struct {
InitCap int `mapstructure:"init_cap"`
MaxCap int `mapstructure:"max_cap"`
Idletimeout int `mapstructure:"idle_timeout"`
}

type MySqlDataSource struct {
name string
config Abstractions.IConfiguration
connectionString string
connPool map[string]Pool.Pool
count int
lock sync.Mutex
log XLog.ILogger
}

// NewMysqlDataSource 初始化MySQL数据源
func NewMysqlDataSource(configuration Abstractions.IConfiguration) *MySqlDataSource {
databaseConfig := configuration.GetSection("yoyogo.datasource.mysql")
var datasourcesConfig dataSourceConfig
databaseConfig.Unmarshal(&datasourcesConfig)
log := XLog.GetXLogger("MysqlDataSource")

p := createMysqlPool(datasourcesConfig, log)

dataSource := &MySqlDataSource{
name: datasourcesConfig.Name,
connectionString: "",
config: configuration,
connPool: make(map[string]Pool.Pool, 0),
log: log,
}
if p != nil {
dataSource.insertPool(datasourcesConfig.Name, p)
}
return dataSource
}

func (datasource *MySqlDataSource) GetName() string {
return datasource.name
}

func (datasource *MySqlDataSource) Open() (conn interface{}, put func(), err error) {

if _, ok := datasource.connPool[datasource.name]; !ok {
return nil, put, errors.New("no mysql connect")
}

conn, err = datasource.connPool[datasource.name].Get()
if err != nil {
return nil, put, errors.New(fmt.Sprintf("mysql get connect err:%v", err))
}

put = func() {
_ = datasource.connPool[datasource.name].Put(conn)
}

return conn, put, nil
}

func (datasource *MySqlDataSource) Close() {
//panic("implement me")
}

func (datasource *MySqlDataSource) Ping() bool {
conn, put, err := datasource.Open()
if err != nil {
return false
}
defer put()
ret := datasource.connPool[datasource.name].Ping(conn) == nil
return ret
}

func (datasource *MySqlDataSource) GetConnectionString() string {
return datasource.connectionString
}

func createMysqlPool(datasourcesConfig dataSourceConfig, log XLog.ILogger) Pool.Pool {
if datasourcesConfig.Pool != nil && (datasourcesConfig.Pool.InitCap == 0 || datasourcesConfig.Pool.MaxCap == 0 || datasourcesConfig.Pool.Idletimeout == 0) {
log.Error("database config is error initCap,maxCap,idleTimeout should be gt 0")
return nil
}

dsnPath := fmt.Sprintf("%s:%s@%s", datasourcesConfig.UserName, datasourcesConfig.Password, datasourcesConfig.Url)

// connMysql 建立连接
connMysql := func() (interface{}, error) {
conn, err := sql.Open("mysql", dsnPath)
return conn, err
}

// closeMysql 关闭连接
closeMysql := func(v interface{}) error {
return v.(*sql.DB).Close()
}

// pingMysql 检测连接连通性
pingMysql := func(v interface{}) error {
conn := v.(*sql.DB)
return conn.Ping()
}

//创建一个连接池: 初始化5,最大连接30
p, err := Pool.NewChannelPool(&Pool.Config{
InitialCap: datasourcesConfig.Pool.InitCap,
MaxCap: datasourcesConfig.Pool.MaxCap,
Factory: connMysql,
Close: closeMysql,
Ping: pingMysql,
//连接最大空闲时间,超过该时间的连接 将会关闭,可避免空闲时连接EOF,自动失效的问题
IdleTimeout: time.Duration(datasourcesConfig.Pool.Idletimeout) * time.Second,
})
if err != nil {
log.Error("register mysql conn [%s] error:%v", datasourcesConfig.Name, err)
return nil
}
return p
}

// insertPool 将连接池插入map,支持多个不同mysql链接
func (datasource *MySqlDataSource) insertPool(name string, p Pool.Pool) {
if datasource.connPool == nil {
datasource.connPool = make(map[string]Pool.Pool, 0)
}
datasource.lock.Lock()
defer datasource.lock.Unlock()
datasource.connPool[name] = p
}
Loading

0 comments on commit 4f6206c

Please sign in to comment.