新增工程

This commit is contained in:
boyce
2019-01-24 16:22:18 +08:00
parent b6add79322
commit 0d4522433d
13 changed files with 2471 additions and 0 deletions

381
cluster/cluster.go Normal file
View File

@@ -0,0 +1,381 @@
package cluster
import (
"fmt"
"log"
"net"
"origin/rpc"
"origin/service"
"os"
"strconv"
"strings"
"time"
)
//https://github.com/rocket049/rpc2d/blob/master/rpcnode.go
//http://daizuozhuo.github.io/golang-rpc-practice/
type RpcClient struct {
nodeid int
pclient *rpc.Client
serverAddr string
isConnect bool
}
type CCluster struct {
port int
cfg *ClusterConfig
nodeclient map[int]*RpcClient
reader net.Conn
writer net.Conn
LocalRpcClient *rpc.Client
}
func (slf *CCluster) ReadNodeInfo(nodeid int) error {
//连接Server结点
var err error
slf.cfg, err = ReadCfg("./config/cluster.json", nodeid)
if err != nil {
fmt.Printf("%v", err)
return nil
}
return nil
}
func (slf *CCluster) GetClusterClient(id int) *rpc.Client {
v, ok := slf.nodeclient[id]
if ok == false {
return nil
}
return v.pclient
}
func (slf *CCluster) GetClusterNode(strNodeName string) *CNodeCfg {
for _, value := range slf.cfg.NodeList {
if value.NodeName == strNodeName {
return &value
}
}
return nil
}
func (slf *CCluster) GetBindUrl() (string, error) {
return slf.cfg.currentNode.ServerAddr, nil
}
type CTestData struct {
Bbbb int64
Cccc int
Ddd string
}
func (slf *CCluster) AcceptRpc(tpcListen *net.TCPListener) error {
slf.reader, slf.writer = net.Pipe()
go rpc.ServeConn(slf.reader)
slf.LocalRpcClient = rpc.NewClient(slf.writer)
for {
conn, err := tpcListen.Accept()
if err != nil {
fmt.Print(err)
return err
}
//使用goroutine单独处理rpc连接请求
go rpc.ServeConn(conn)
}
return nil
}
func (slf *CCluster) ListenService() error {
bindStr, err := slf.GetBindUrl()
if err != nil {
return err
}
tcpaddr, err := net.ResolveTCPAddr("tcp4", bindStr)
if err != nil {
return err
}
tcplisten, err2 := net.ListenTCP("tcp", tcpaddr)
if err2 != nil {
return err2
}
go slf.AcceptRpc(tcplisten)
return nil
}
type CPing struct {
TimeStamp int64
}
type CPong struct {
TimeStamp int64
}
func (slf *CPing) Ping(ping *CPing, pong *CPong) error {
pong.TimeStamp = ping.TimeStamp
return nil
}
func (slf *CCluster) ConnService() error {
ping := CPing{0}
pong := CPong{0}
fmt.Println(rpc.RegisterName("CPing", &ping))
//连接集群服务器
for _, nodeList := range slf.cfg.mapClusterNodeService {
for _, node := range nodeList {
slf.nodeclient[node.NodeID] = &RpcClient{node.NodeID, nil, node.ServerAddr, false}
}
}
for {
for _, rpcClient := range slf.nodeclient {
//
if rpcClient.isConnect == true {
ping.TimeStamp = 0
err := rpcClient.pclient.Call("CPing.Ping", &ping, &pong)
if err != nil {
rpcClient.pclient.Close()
rpcClient.pclient = nil
rpcClient.isConnect = false
continue
}
continue
}
if rpcClient.pclient != nil {
rpcClient.pclient.Close()
rpcClient.pclient = nil
}
client, err := rpc.Dial("tcp", rpcClient.serverAddr)
if err != nil {
log.Println(err)
continue
}
v, _ := slf.nodeclient[rpcClient.nodeid]
v.pclient = client
v.isConnect = true
}
time.Sleep(time.Second * 2)
}
return nil
}
func (slf *CCluster) Init() error {
if len(os.Args) < 2 {
return fmt.Errorf("param error not find NodeId=number")
}
parts := strings.Split(os.Args[1], "=")
if len(parts) < 2 {
return fmt.Errorf("param error not find NodeId=number")
}
if parts[0] != "NodeId" {
return fmt.Errorf("param error not find NodeId=number")
}
slf.nodeclient = make(map[int]*RpcClient)
//读取配置
ret, err := strconv.Atoi(parts[1])
if err != nil {
return err
}
return slf.ReadNodeInfo(ret)
}
func (slf *CCluster) Start() error {
service.InstanceServiceMgr().FetchService(slf.OnFetchService)
//监听服务
slf.ListenService()
//集群
go slf.ConnService()
return nil
}
//Node.servicename.methodname
//servicename.methodname
//_servicename.methodname
func (slf *CCluster) Call(NodeServiceMethod string, args interface{}, reply interface{}) error {
var callServiceName string
nodeidList := slf.GetNodeList(NodeServiceMethod, &callServiceName)
if len(nodeidList) > 1 {
return fmt.Errorf("Call: %s find %d nodes.", NodeServiceMethod, len(nodeidList))
}
for _, nodeid := range nodeidList {
if nodeid == slf.GetCurrentNodeId() {
return slf.LocalRpcClient.Call(callServiceName, args, reply)
} else {
pclient := slf.GetClusterClient(nodeid)
if pclient == nil {
return fmt.Errorf("Call: NodeId %d is not find.", nodeid)
}
err := pclient.Call(callServiceName, args, reply)
return err
}
}
return fmt.Errorf("Call: %s fail.", NodeServiceMethod)
}
func (slf *CCluster) GetNodeList(NodeServiceMethod string, rpcServerMethod *string) []int {
var nodename string
var servicename string
var methodname string
var nodeidList []int
parts := strings.Split(NodeServiceMethod, ".")
if len(parts) == 2 {
servicename = parts[0]
methodname = parts[1]
} else if len(parts) == 3 {
nodename = parts[0]
servicename = parts[1]
methodname = parts[2]
} else {
return nodeidList
}
if nodename == "" {
nodeidList = make([]int, 0)
if servicename[:1] == "_" {
servicename = servicename[1:]
nodeidList = append(nodeidList, slf.GetCurrentNodeId())
} else {
nodeidList = slf.cfg.GetIdByService(servicename)
}
} else {
nodeidList = slf.GetIdByNodeService(nodename, servicename)
}
*rpcServerMethod = servicename + "." + methodname
return nodeidList
}
func (slf *CCluster) Go(NodeServiceMethod string, args interface{}) error {
var callServiceName string
nodeidList := slf.GetNodeList(NodeServiceMethod, &callServiceName)
if len(nodeidList) > 1 {
return fmt.Errorf("Call: %s find %d nodes.", NodeServiceMethod, len(nodeidList))
}
for _, nodeid := range nodeidList {
if nodeid == slf.GetCurrentNodeId() {
slf.LocalRpcClient.Go(callServiceName, args, nil, nil)
return nil
} else {
pclient := slf.GetClusterClient(nodeid)
if pclient == nil {
return fmt.Errorf("Call: NodeId %d is not find.", nodeid)
}
pclient.Go(callServiceName, args, nil, nil)
return nil
}
}
return fmt.Errorf("Call: %s fail.", NodeServiceMethod)
}
func (slf *CCluster) CallNode(nodeid int, servicemethod string, args interface{}, reply interface{}) error {
pclient := slf.GetClusterClient(nodeid)
if pclient == nil {
return fmt.Errorf("Call: NodeId %d is not find.", nodeid)
}
err := pclient.Call(servicemethod, args, reply)
return err
}
func (slf *CCluster) GoNode(nodeid int, args interface{}, servicemethod string) error {
pclient := slf.GetClusterClient(nodeid)
if pclient == nil {
return fmt.Errorf("Call: NodeId %d is not find.", nodeid)
}
replyCall := pclient.Go(servicemethod, args, nil, nil)
//ret := <-replyCall.Done
if replyCall.Error != nil {
fmt.Print(replyCall.Error)
}
//fmt.Print(ret)
return nil
}
func (ws *CCluster) OnFetchService(iservice service.IService) error {
rpc.RegisterName(iservice.GetServiceName(), iservice)
return nil
}
//向远程服务器调用
//Node.servicename.methodname
//servicename.methodname
func Call(NodeServiceMethod string, args interface{}, reply interface{}) error {
return InstanceClusterMgr().Call(NodeServiceMethod, args, reply)
}
func Go(NodeServiceMethod string, args interface{}) error {
return InstanceClusterMgr().Go(NodeServiceMethod, args)
}
func CallNode(NodeId int, servicemethod string, args interface{}, reply interface{}) error {
return InstanceClusterMgr().CallNode(NodeId, servicemethod, args, reply)
}
func GoNode(NodeId int, servicemethod string, args interface{}) error {
return InstanceClusterMgr().GoNode(NodeId, args, servicemethod)
}
func CastCall(NodeServiceMethod string, args interface{}, reply []interface{}) error {
return InstanceClusterMgr().Call(NodeServiceMethod, args, reply)
}
var _self *CCluster
func InstanceClusterMgr() *CCluster {
if _self == nil {
_self = new(CCluster)
return _self
}
return _self
}
func (slf *CCluster) GetIdByNodeService(NodeName string, serviceName string) []int {
return slf.cfg.GetIdByNodeService(NodeName, serviceName)
}
func (slf *CCluster) HasLocalService(serviceName string) bool {
return slf.cfg.HasLocalService(serviceName)
}
func (slf *CCluster) GetCurrentNodeId() int {
return slf.cfg.currentNode.NodeID
}

144
cluster/config.go Normal file
View File

@@ -0,0 +1,144 @@
package cluster
import (
"encoding/json"
"fmt"
"io/ioutil"
)
type CNodeCfg struct {
NodeID int
NodeName string
ServerAddr string
ServiceList []string
ClusterNode []string
}
type CNode struct {
NodeID int
NodeName string
ServerAddr string
ServiceList map[string]bool
}
type ClusterConfig struct {
NodeList []CNodeCfg
//通过id获取结点
mapIdNode map[int]CNode
//map[nodename][ {CNode} ]
mapClusterNodeService map[string][]CNode
mapClusterServiceNode map[string][]CNode
mapLocalService map[string]bool
currentNode CNode
}
// ReadCfg ...
func ReadCfg(path string, nodeid int) (*ClusterConfig, error) {
c := &ClusterConfig{}
d, err := ioutil.ReadFile(path)
if err != nil {
return nil, err
}
err = json.Unmarshal(d, c)
if err != nil {
return nil, err
}
c.mapIdNode = make(map[int]CNode, 1)
c.mapClusterNodeService = make(map[string][]CNode, 1)
c.mapLocalService = make(map[string]bool)
c.mapClusterServiceNode = make(map[string][]CNode, 1)
//组装mapIdNode
var clusterNode []string
for _, v := range c.NodeList {
//1.取所有结点
mapservice := make(map[string]bool, 1)
c.mapIdNode[v.NodeID] = CNode{v.NodeID, v.NodeName, v.ServerAddr, mapservice}
if nodeid == v.NodeID {
c.currentNode = c.mapIdNode[v.NodeID]
//2.mapServiceNode map[string][]string
for _, s := range v.ServiceList {
mapservice[s] = true
c.mapLocalService[s] = true
}
for _, c := range v.ClusterNode {
clusterNode = append(clusterNode, c)
}
}
}
//组装mapClusterNodeService
for _, kc := range clusterNode {
for _, v := range c.NodeList {
if kc == v.NodeName {
//将自有连接的结点取详细信息
mapservice := make(map[string]bool, 1)
curNode := CNode{v.NodeID, v.NodeName, v.ServerAddr, mapservice}
for _, s := range v.ServiceList {
mapservice[s] = true
c.mapClusterServiceNode[s] = append(c.mapClusterServiceNode[s], curNode)
}
c.mapClusterNodeService[v.NodeName] = append(c.mapClusterNodeService[v.NodeName], curNode)
}
}
}
fmt.Println(c.mapIdNode)
fmt.Println(c.mapClusterNodeService)
fmt.Println(c.mapClusterServiceNode)
return c, nil
}
func (slf *ClusterConfig) GetIdByService(serviceName string) []int {
var nodeidlist []int
nodeidlist = make([]int, 0)
nodeList, ok := slf.mapClusterServiceNode[serviceName]
if ok == true {
for _, v := range nodeList {
nodeidlist = append(nodeidlist, v.NodeID)
}
}
return nodeidlist
}
func (slf *ClusterConfig) GetIdByNodeService(NodeName string, serviceName string) []int {
var nodeidlist []int
nodeidlist = make([]int, 0)
if NodeName == slf.currentNode.NodeName {
nodeidlist = append(nodeidlist, slf.currentNode.NodeID)
}
v, ok := slf.mapClusterNodeService[NodeName]
if ok == false {
return nodeidlist
}
for _, n := range v {
_, ok = n.ServiceList[serviceName]
if ok == true {
nodeidlist = append(nodeidlist, n.NodeID)
}
}
return nodeidlist
}
func (slf *ClusterConfig) HasLocalService(serviceName string) bool {
_, ok := slf.mapLocalService[serviceName]
return ok == true
}