mirror of
https://github.com/duanhf2012/origin.git
synced 2026-03-02 03:04:49 +08:00
优化新增rpc压缩功能
This commit is contained in:
@@ -16,7 +16,7 @@ type memAreaPool struct {
|
|||||||
pool []sync.Pool
|
pool []sync.Pool
|
||||||
}
|
}
|
||||||
|
|
||||||
var memAreaPoolList = [3]*memAreaPool{&memAreaPool{minAreaValue: 1, maxAreaValue: 4096, growthValue: 512}, &memAreaPool{minAreaValue: 4097, maxAreaValue: 40960, growthValue: 4096}, &memAreaPool{minAreaValue: 40961, maxAreaValue: 417792, growthValue: 16384}}
|
var memAreaPoolList = [4]*memAreaPool{&memAreaPool{minAreaValue: 1, maxAreaValue: 4096, growthValue: 512}, &memAreaPool{minAreaValue: 4097, maxAreaValue: 40960, growthValue: 4096}, &memAreaPool{minAreaValue: 40961, maxAreaValue: 417792, growthValue: 16384}, &memAreaPool{minAreaValue: 417793, maxAreaValue: 1925120, growthValue: 65536}}
|
||||||
|
|
||||||
func init() {
|
func init() {
|
||||||
for i := 0; i < len(memAreaPoolList); i++ {
|
for i := 0; i < len(memAreaPoolList); i++ {
|
||||||
|
|||||||
@@ -5,18 +5,20 @@ import (
|
|||||||
"errors"
|
"errors"
|
||||||
"github.com/pierrec/lz4/v4"
|
"github.com/pierrec/lz4/v4"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/duanhf2012/origin/network"
|
||||||
)
|
)
|
||||||
|
|
||||||
type ICompressor interface {
|
var memPool network.INetMempool = network.NewMemAreaPool()
|
||||||
CompressBlock(src, dst []byte) ([]byte,int, error) //dst如果有预申请使用dst内存,传入nil时内部申请
|
|
||||||
UncompressBlock(src []byte, dst []byte) ([]byte,int, error)//dst如果有预申请使用dst内存,传入nil时内部申请
|
|
||||||
|
|
||||||
CompressBlockBound(n int) int
|
type ICompressor interface {
|
||||||
UnCompressBlockBound(n int) int
|
CompressBlock(src []byte) ([]byte, error) //dst如果有预申请使用dst内存,传入nil时内部申请
|
||||||
|
UncompressBlock(src []byte) ([]byte, error)//dst如果有预申请使用dst内存,传入nil时内部申请
|
||||||
|
|
||||||
|
CompressBufferCollection(buffer []byte) //压缩的Buffer内存回收
|
||||||
|
UnCompressBufferCollection(buffer []byte) //解压缩的Buffer内存回收
|
||||||
}
|
}
|
||||||
|
|
||||||
var compressor ICompressor
|
var compressor ICompressor
|
||||||
|
|
||||||
func init(){
|
func init(){
|
||||||
SetCompressor(&Lz4Compressor{})
|
SetCompressor(&Lz4Compressor{})
|
||||||
}
|
}
|
||||||
@@ -28,7 +30,7 @@ func SetCompressor(cp ICompressor){
|
|||||||
type Lz4Compressor struct {
|
type Lz4Compressor struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *Lz4Compressor) CompressBlock(src, dst []byte) (dest []byte,cnt int, err error) {
|
func (lc *Lz4Compressor) CompressBlock(src []byte) (dest []byte, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
@@ -38,19 +40,31 @@ func (lc *Lz4Compressor) CompressBlock(src, dst []byte) (dest []byte,cnt int, er
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
dest = dst
|
|
||||||
var c lz4.Compressor
|
var c lz4.Compressor
|
||||||
maxCompressSize := lc.CompressBlockBound(len(src))
|
var cnt int
|
||||||
if len(dest) < maxCompressSize {
|
dest = memPool.MakeByteSlice(lz4.CompressBlockBound(len(src))+1)
|
||||||
dest = make([]byte,maxCompressSize)
|
cnt, err = c.CompressBlock(src, dest[1:])
|
||||||
|
if err != nil {
|
||||||
|
memPool.ReleaseByteSlice(dest)
|
||||||
|
return nil,err
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt, err = c.CompressBlock(src, dest)
|
ratio := len(src) / cnt
|
||||||
|
if len(src) % cnt > 0 {
|
||||||
|
ratio += 1
|
||||||
|
}
|
||||||
|
|
||||||
|
if ratio > 255 {
|
||||||
|
memPool.ReleaseByteSlice(dest)
|
||||||
|
return nil,fmt.Errorf("Impermissible errors")
|
||||||
|
}
|
||||||
|
|
||||||
|
dest[0] = uint8(ratio)
|
||||||
|
dest = dest[:cnt+1]
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *Lz4Compressor) UncompressBlock(src, dst []byte) (dest []byte,cnt int, err error) {
|
func (lc *Lz4Compressor) UncompressBlock(src []byte) (dest []byte, err error) {
|
||||||
defer func() {
|
defer func() {
|
||||||
if r := recover(); r != nil {
|
if r := recover(); r != nil {
|
||||||
buf := make([]byte, 4096)
|
buf := make([]byte, 4096)
|
||||||
@@ -60,22 +74,29 @@ func (lc *Lz4Compressor) UncompressBlock(src, dst []byte) (dest []byte,cnt int,
|
|||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
|
|
||||||
dest = dst
|
radio := uint8(src[0])
|
||||||
maxUncompressSize := lc.UnCompressBlockBound(len(src))
|
if radio == 0 {
|
||||||
if len(dest) < maxUncompressSize {
|
return nil,fmt.Errorf("Impermissible errors")
|
||||||
dest = make([]byte,maxUncompressSize)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cnt, err = lz4.UncompressBlock(src, dest)
|
dest = memPool.MakeByteSlice(len(src)*int(radio))
|
||||||
return
|
cnt, err := lz4.UncompressBlock(src[1:], dest)
|
||||||
|
if err != nil {
|
||||||
|
memPool.ReleaseByteSlice(dest)
|
||||||
|
return nil,err
|
||||||
|
}
|
||||||
|
|
||||||
|
return dest[:cnt],nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *Lz4Compressor) CompressBlockBound(n int) int{
|
func (lc *Lz4Compressor) compressBlockBound(n int) int{
|
||||||
return lz4.CompressBlockBound(n)
|
return lz4.CompressBlockBound(n)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (lc *Lz4Compressor) UnCompressBlockBound(n int) int{
|
func (lc *Lz4Compressor) CompressBufferCollection(buffer []byte){
|
||||||
return n*10
|
memPool.ReleaseByteSlice(buffer)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (lc *Lz4Compressor) UnCompressBufferCollection(buffer []byte) {
|
||||||
|
memPool.ReleaseByteSlice(buffer)
|
||||||
|
}
|
||||||
@@ -14,8 +14,6 @@ import (
|
|||||||
|
|
||||||
//跨结点连接的Client
|
//跨结点连接的Client
|
||||||
type RClient struct {
|
type RClient struct {
|
||||||
compressBuff []byte
|
|
||||||
|
|
||||||
compressBytesLen int
|
compressBytesLen int
|
||||||
selfClient *Client
|
selfClient *Client
|
||||||
network.TCPClient
|
network.TCPClient
|
||||||
@@ -84,19 +82,19 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
|
|||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var compressBuff[]byte
|
||||||
bCompress := uint8(0)
|
bCompress := uint8(0)
|
||||||
if rc.compressBytesLen > 0 && len(bytes) >= rc.compressBytesLen {
|
if rc.compressBytesLen > 0 && len(bytes) >= rc.compressBytesLen {
|
||||||
var cnt int
|
|
||||||
var cErr error
|
var cErr error
|
||||||
rc.compressBuff,cnt,cErr = compressor.CompressBlock(bytes,rc.compressBuff[:])
|
compressBuff,cErr = compressor.CompressBlock(bytes)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
call.Seq = 0
|
call.Seq = 0
|
||||||
log.SError(err.Error())
|
log.SError(cErr.Error())
|
||||||
call.DoError(err)
|
call.DoError(cErr)
|
||||||
return call
|
return call
|
||||||
}
|
}
|
||||||
if cnt < len(bytes) {
|
if len(compressBuff) < len(bytes) {
|
||||||
bytes = rc.compressBuff[:cnt]
|
bytes = compressBuff
|
||||||
bCompress = 1<<7
|
bCompress = 1<<7
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -106,6 +104,12 @@ func (rc *RClient) RawGo(rpcHandler IRpcHandler,processor IRpcProcessor, noReply
|
|||||||
}
|
}
|
||||||
|
|
||||||
err = conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
|
err = conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
|
||||||
|
if cap(compressBuff) >0 {
|
||||||
|
compressor.CompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
|
if cap(compressBuff) >0 {
|
||||||
|
compressor.CompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rc.selfClient.RemovePending(call.Seq)
|
rc.selfClient.RemovePending(call.Seq)
|
||||||
|
|
||||||
@@ -148,18 +152,17 @@ func (rc *RClient) asyncCall(timeout time.Duration,rpcHandler IRpcHandler, servi
|
|||||||
return emptyCancelRpc,errors.New("Rpc server is disconnect,call " + serviceMethod)
|
return emptyCancelRpc,errors.New("Rpc server is disconnect,call " + serviceMethod)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var compressBuff[]byte
|
||||||
bCompress := uint8(0)
|
bCompress := uint8(0)
|
||||||
if rc.compressBytesLen>0 &&len(bytes) >= rc.compressBytesLen {
|
if rc.compressBytesLen>0 &&len(bytes) >= rc.compressBytesLen {
|
||||||
var cnt int
|
|
||||||
var cErr error
|
var cErr error
|
||||||
|
compressBuff,cErr = compressor.CompressBlock(bytes)
|
||||||
rc.compressBuff,cnt,cErr = compressor.CompressBlock(bytes,rc.compressBuff[:])
|
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
return emptyCancelRpc,cErr
|
return emptyCancelRpc,cErr
|
||||||
}
|
}
|
||||||
|
|
||||||
if cnt < len(bytes) {
|
if len(compressBuff) < len(bytes) {
|
||||||
bytes = rc.compressBuff[:cnt]
|
bytes = compressBuff
|
||||||
bCompress = 1<<7
|
bCompress = 1<<7
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -174,6 +177,9 @@ func (rc *RClient) asyncCall(timeout time.Duration,rpcHandler IRpcHandler, servi
|
|||||||
rc.selfClient.AddPending(call)
|
rc.selfClient.AddPending(call)
|
||||||
|
|
||||||
err = conn.WriteMsg([]byte{uint8(processorType)|bCompress}, bytes)
|
err = conn.WriteMsg([]byte{uint8(processorType)|bCompress}, bytes)
|
||||||
|
if cap(compressBuff) >0 {
|
||||||
|
compressor.CompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
if err != nil {
|
if err != nil {
|
||||||
rc.selfClient.RemovePending(call.Seq)
|
rc.selfClient.RemovePending(call.Seq)
|
||||||
ReleaseCall(call)
|
ReleaseCall(call)
|
||||||
@@ -221,20 +227,23 @@ func (rc *RClient) Run() {
|
|||||||
|
|
||||||
//解压缩
|
//解压缩
|
||||||
byteData := bytes[1:]
|
byteData := bytes[1:]
|
||||||
|
var compressBuff []byte
|
||||||
if bCompress == true {
|
if bCompress == true {
|
||||||
var cnt int
|
|
||||||
var unCompressErr error
|
var unCompressErr error
|
||||||
|
|
||||||
rc.compressBuff,cnt,unCompressErr = compressor.UncompressBlock(byteData,rc.compressBuff[:])
|
compressBuff,unCompressErr = compressor.UncompressBlock(byteData)
|
||||||
if unCompressErr!= nil {
|
if unCompressErr!= nil {
|
||||||
rc.conn.ReleaseReadMsg(bytes)
|
rc.conn.ReleaseReadMsg(bytes)
|
||||||
log.SError("rpcClient ", rc.Addr, " ReadMsg head error:", err.Error())
|
log.SError("rpcClient ", rc.Addr, " ReadMsg head error:", unCompressErr.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
byteData = rc.compressBuff[:cnt]
|
byteData = compressBuff
|
||||||
}
|
}
|
||||||
|
|
||||||
err = processor.Unmarshal(byteData, response.RpcResponseData)
|
err = processor.Unmarshal(byteData, response.RpcResponseData)
|
||||||
|
if cap(compressBuff) > 0 {
|
||||||
|
compressor.UnCompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
rc.conn.ReleaseReadMsg(bytes)
|
rc.conn.ReleaseReadMsg(bytes)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
processor.ReleaseRpcResponse(response.RpcResponseData)
|
processor.ReleaseRpcResponse(response.RpcResponseData)
|
||||||
|
|||||||
@@ -35,8 +35,6 @@ type RpcAgent struct {
|
|||||||
conn network.Conn
|
conn network.Conn
|
||||||
rpcServer *Server
|
rpcServer *Server
|
||||||
userData interface{}
|
userData interface{}
|
||||||
|
|
||||||
compressBuff []byte
|
|
||||||
}
|
}
|
||||||
|
|
||||||
func AppendProcessor(rpcProcessor IRpcProcessor) {
|
func AppendProcessor(rpcProcessor IRpcProcessor) {
|
||||||
@@ -117,23 +115,26 @@ func (agent *RpcAgent) WriteResponse(processor IRpcProcessor, serviceMethod stri
|
|||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var compressBuff[]byte
|
||||||
bCompress := uint8(0)
|
bCompress := uint8(0)
|
||||||
if agent.rpcServer.compressBytesLen >0 && len(bytes) >= agent.rpcServer.compressBytesLen {
|
if agent.rpcServer.compressBytesLen >0 && len(bytes) >= agent.rpcServer.compressBytesLen {
|
||||||
var cnt int
|
|
||||||
var cErr error
|
var cErr error
|
||||||
|
|
||||||
agent.compressBuff,cnt,cErr = compressor.CompressBlock(bytes,agent.compressBuff[:])
|
compressBuff,cErr = compressor.CompressBlock(bytes)
|
||||||
if cErr != nil {
|
if cErr != nil {
|
||||||
log.SError("service method ", serviceMethod, " CompressBlock error:", errM.Error())
|
log.SError("service method ", serviceMethod, " CompressBlock error:", cErr.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if cnt < len(bytes) {
|
if len(compressBuff) < len(bytes) {
|
||||||
bytes = agent.compressBuff[:cnt]
|
bytes = compressBuff
|
||||||
bCompress = 1<<7
|
bCompress = 1<<7
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
errM = agent.conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
|
errM = agent.conn.WriteMsg([]byte{uint8(processor.GetProcessorType())|bCompress}, bytes)
|
||||||
|
if cap(compressBuff) >0 {
|
||||||
|
compressor.CompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
if errM != nil {
|
if errM != nil {
|
||||||
log.SError("Rpc ", serviceMethod, " return is error:", errM.Error())
|
log.SError("Rpc ", serviceMethod, " return is error:", errM.Error())
|
||||||
}
|
}
|
||||||
@@ -157,22 +158,25 @@ func (agent *RpcAgent) Run() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
//解析head
|
//解析head
|
||||||
|
var compressBuff []byte
|
||||||
byteData := data[1:]
|
byteData := data[1:]
|
||||||
if bCompress == true {
|
if bCompress == true {
|
||||||
var cnt int
|
|
||||||
var unCompressErr error
|
var unCompressErr error
|
||||||
|
|
||||||
agent.compressBuff,cnt,unCompressErr = compressor.UncompressBlock(byteData,agent.compressBuff[:])
|
compressBuff,unCompressErr = compressor.UncompressBlock(byteData)
|
||||||
if unCompressErr!= nil {
|
if unCompressErr!= nil {
|
||||||
agent.conn.ReleaseReadMsg(data)
|
agent.conn.ReleaseReadMsg(data)
|
||||||
log.SError("rpcClient ", agent.conn.RemoteAddr(), " ReadMsg head error:", err.Error())
|
log.SError("rpcClient ", agent.conn.RemoteAddr(), " ReadMsg head error:", unCompressErr.Error())
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
byteData = agent.compressBuff[:cnt]
|
byteData = compressBuff
|
||||||
}
|
}
|
||||||
|
|
||||||
req := MakeRpcRequest(processor, 0, 0, "", false, nil)
|
req := MakeRpcRequest(processor, 0, 0, "", false, nil)
|
||||||
err = processor.Unmarshal(byteData, req.RpcRequestData)
|
err = processor.Unmarshal(byteData, req.RpcRequestData)
|
||||||
|
if cap(compressBuff) > 0 {
|
||||||
|
compressor.UnCompressBufferCollection(compressBuff)
|
||||||
|
}
|
||||||
agent.conn.ReleaseReadMsg(data)
|
agent.conn.ReleaseReadMsg(data)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
log.SError("rpc Unmarshal request is error:", err.Error())
|
log.SError("rpc Unmarshal request is error:", err.Error())
|
||||||
|
|||||||
Reference in New Issue
Block a user