• 运行时间统计

    运行时间统计

    有时候,我们希望能够对调用执行时间做一个统计,对于客户端来说,也就是客户端调用发出前,到客户端收到调用结果的时间统计。对于服务器来说,就是收到客户端调用请求到要发出调用结果的这一段时间的统计。这个功能,通过过滤器也可以实现。

    stat_filter.go

    1. package main
    2.  
    3. import (
    4. "fmt"
    5. "time"
    6.  
    7. "github.com/hprose/hprose-golang/rpc"
    8. )
    9.  
    10. type StatFilter struct {
    11. Prompt string
    12. }
    13.  
    14. func (sf StatFilter) stat(context rpc.Context) {
    15. startTime := context.GetInt64("startTime")
    16. if startTime > 0 {
    17. fmt.Printf("%v takes %d ns.\r\n", sf.Prompt, time.Now().UnixNano()-startTime)
    18. } else {
    19. context.SetInt64("startTime", time.Now().UnixNano())
    20. }
    21. }
    22.  
    23. func (sf StatFilter) InputFilter(data []byte, context rpc.Context) []byte {
    24. sf.stat(context)
    25. return data
    26. }
    27.  
    28. func (sf StatFilter) OutputFilter(data []byte, context rpc.Context) []byte {
    29. sf.stat(context)
    30. return data
    31. }

    main.go

    1. package main
    2.  
    3. import "github.com/hprose/hprose-golang/rpc"
    4.  
    5. func hello(name string) string {
    6. return "Hello " + name + "!"
    7. }
    8.  
    9. // HelloService is ...
    10. type HelloService struct {
    11. Hello func(string) (string, error)
    12. }
    13.  
    14. func main() {
    15. server := rpc.NewTCPServer("")
    16. server.AddFunction("hello", hello).AddFilter(StatFilter{"Server"})
    17. server.Handle()
    18. client := rpc.NewClient(server.URI())
    19. client.AddFilter(StatFilter{"Client"})
    20. var helloService *HelloService
    21. client.UseService(&helloService)
    22. for i := 0; i < 3; i++ {
    23. helloService.Hello("World")
    24. }
    25. client.Close()
    26. server.Close()
    27. }

    运行该程序,你会看到运行结果:


    1. Server takes 47303 ns.
    2. Client takes 315459 ns.
    3. Server takes 6846 ns.
    4. Client takes 68138 ns.
    5. Server takes 5601 ns.
    6. Client takes 64499 ns.

    我们看到后面的调用明显要比第一次调用快的多,这是因为第一次调用涉及到 TCP 连接的建立,以及缓存初始化等操作,一旦这些操作完成了,接下来就会很快了。

    在这个程序中,我们还看到了 Context 的应用方式,当然 Context 能做的事情不止于此,后面我们还会看到它的更多功能。