9 27
C语言字符指针与数组

基本概念

字符串是C语言中最有用、最重要的数据类型之一,在C语言里面,字符串常量是一个字符数组,例如:

"I am a string"

在字符串的内部表示中,字符数组以空字符 '\0' 结尾的char类型数组,所以程序可以通过检查空字符找到字符数组的结尾。字符串常量占据的存储单元数也因此比双引号内的字符数大1

字符串常量最常见的用法也许是作为函数参数,例如:

9 20
squid安装与部署

前阵子开始构思用go+leveldb实现一个分布式缓存方案,顺便调研了一下squid,下面是这阵子对squid的一些总结:

代理缓存服务很多,squid是其中一个比较成熟的工具(类似的有:varnish、ATS、nginx-proxycache等)。Squid用途广泛的,可以作为缓存服务器,可以过滤流量帮助网络安全,也可以作为代理服务器链中的一环,向上级代理转发数据或直接连接互联网。

squid cache的总体架构可以理解为下图的展示方式

sq1

我们主要针对squid的缓存功能,下面会详细介绍:

9 11
最近工作点滴

在目前这家电商公司刚好满两年,我觉得是时候简单总结一下最近的一些工作吧:

最近公司内部人员调整算是比较大的, 按照leader的想法, 我这边下半年开始往基础架构的建设上下更大的功夫。 而且临近双十一,相关挑战也接踵而来:目前一个”水深火热”的问题是我们内部某个基础底层的服务需要增加更可靠的分布式缓存支持日益递增的业务请求压力;

虽然说目前市面上的分布式缓存手段繁多,外面每个大厂分享的”PPT”描述得好像都很有道理,但能结合目前我们的问题的方案可就显得力不从心了,更何况当今的后端研发人员,一说到分布式缓存,不把memcache/redis挂在嘴上,都不好意思说自己懂后端开发了,但被问到如何解决实际的问题与策略,很多人就吞吞吐吐了。所以我们内部也开始研究乃至自己编写相关分布式缓存技术的组件, 希望能抗住目前项目所带来的巨大请求压力.

典型的分布式缓存思路无非就是使用类似KV形式存储和访问数据,在内存中维护一张巨大的HashTable,然后根据相关的路由算法将key进行Hash,使得在读数据是首先读缓存(内存)。如果缓存中没有数据,那么再去读存储(磁盘),并且把数据写入缓存。最终对数据查询的时间复杂度降低到O(1),保证了对数据的高性能访问。

这种手段放之四海而皆准。但往深入想一下,会发现这都是很表面的套路,一个健壮的分布式缓存应该需要同时解决以下的问题:

  • 扩容问题

  • 故障恢复

  • 存储一致性

  • 高效的读写

  • 过载保护

  • 预热功能

上述的问题,我先抛出来,主要做一个记录,先不详细说明,这段时间我会结合不断的实践,到时如果有所收获的话,再提炼相关经验分享出来吧。

6 29
Golang版protobuf的安装与使用

Protobuf 介绍

序列化库在网络传输,RPC,数据库访问等环境中经常用到,它的性能的好坏直接影响着整个产品的性能, 所以我们有必要对一些优秀的序列化库进一步的学习与掌握.

protobuf是Google开发的一种数据描述语言语言,能够将结构化的数据序列化,可用于数据存储,通信协议等方面,官方版本支持 Go, C++, Java, Python,社区版本支持更多语言.

相对于JSON和XML具有以下优点:

  • 简洁

  • 体积小:消息大小只需要XML的1/10 ~ 13

  • 速度快:解析速度比XML快20 ~ 100倍

  • 使用Protobuf的编译器,可以生成更容易在编程中使用的数据访问代码

  • 更好的兼容性,Protobuf设计的一个原则就是要能够很好的支持向下或向上兼容

本文主要以Go语言的方式来具体讲述如何使用Pb进行数据的定义与传输

Protobuf 使用

安装

1.从 https://github.com/google/protobuf/releases 获取 Protobuf 编译器 protoc

wget https://github.com/google/protobuf/releases/download/v2.6.1/protobuf-2.6.1.tar.gztar zxvf protobuf-2.6.1.tar.gz
cd protobuf-2.6.1./configure
make
make install
protoc   -h

2.获取 goprotobuf 提供的 Protobuf 插件 protoc-gen-go(被放置于 $GOPATH/bin 下,$GOPATH/bin 应该被加入 PATH 环境变量,以便 protoc 能够找到 protoc-gen-go)

此插件被 protoc 使用,用于编译 .proto 文件为 Golang 源文件,通过此源文件可以使用定义在 .proto 文件中的消息。

go get github.com/golang/protobuf/protoc-gen-go
 
cd github.com/golang/protobuf/protoc-gen-go
 
go build
 
go install
 
vi /etc/profile 将$GOPATH/bin 加入环境变量
 
source profile

3.获取 goprotobuf 提供的支持库,包含诸如编码(marshaling)、解码(unmarshaling)等功能

go get github.com/golang/protobuf/proto
cd github.com/golang/protobuf/proto
go build
go install

使用 go protobuf

接着, 我们进行数据格式的定义, 写一个简单的例子: 我们在 $GOPATH下新建一个测试项目 pblearn/packet 在 $GOPATH/pblearn/packet 下, 创建一个名为 packet.proto 的文件, 然后编写如下的内容

package packet;
message Header{
    required string messageId = 1;
    required string topic = 2; //topic类型
}
//byte类消息
message BytesMessage{
    required Header  header= 1;
    required  bytes body = 2;    
}
//string类型的message
message StringMessage{
    required Header header = 1;
    required string body = 2;
}

然后通过 –go_out 来使用 goprotobuf 提供的 Protobuf 插件 protoc-gen-go。这时候我们会生成一个名为 test.pb.go 的源文件, 参考如下

protoc --go_out=. *.proto

命令执行后, pblearn/packet 下会生成一个go的文件 packet.pb.go, 这个就是我们消息操作对象

最后,我们可以编写测试例子, 在 在 $GOPATH/pblearn/ 下,我们编写 main.go

package main
 
import (
    // 辅助库
    "github.com/golang/protobuf/proto"
    // test.pb.go 的路径
    "pblearn/packet"
)
 
func main() {
 
    bodyData := "guangzhou/fangcun/vip/company"
 
    p := &packet.StringMessage{
        Body: proto.String(bodyData),
        Header: &packet.Header{
            MessageId: proto.String("20-05"),
            Topic:     proto.String("golang"),
        },
    }
 
    pData, err := proto.Marshal(p)
 
    if err != nil {
        println(err.Error())
    }
    println(string(pData))
 
    p2 := &packet.StringMessage{}
    proto.Unmarshal(pData, p2)
 
    println(p2.GetHeader().GetTopic())
}

通过运行例子 go run main.go 可以发现, 我们的数据格式可以正常的序列化和反序列化了.

这样,我们日后可以根据自己的业务需要, 进行高效的数据传输

前一页 后一页