You are viewing a plain text version of this content. The canonical link for it is here.
Posted to notifications@skywalking.apache.org by wu...@apache.org on 2020/04/09 07:56:09 UTC

[skywalking-nginx-lua] branch master updated: Adapt the new v3 protocol (#30)

This is an automated email from the ASF dual-hosted git repository.

wusheng pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/skywalking-nginx-lua.git


The following commit(s) were added to refs/heads/master by this push:
     new d754b89  Adapt the new v3 protocol (#30)
d754b89 is described below

commit d754b89692fc147ab7447da4f456f6b442985bb1
Author: mrproliu <74...@qq.com>
AuthorDate: Thu Apr 9 15:56:03 2020 +0800

    Adapt the new v3 protocol (#30)
    
    * adapt the new v3 protocol
---
 .github/workflows/ci.yaml                          |  11 +-
 .github/workflows/e2e.yaml                         |  10 +-
 LICENSE                                            |   2 +-
 README.md                                          |  26 +-
 examples/nginx.conf                                |  37 +-
 lib/skywalking/client.lua                          | 133 ++-----
 lib/skywalking/{util_test.lua => management.lua}   |  36 +-
 lib/skywalking/register.lua                        |  66 ----
 lib/skywalking/resty/jit-uuid.lua                  | 425 +++++++++++++++++++++
 lib/skywalking/segment.lua                         |  24 +-
 lib/skywalking/segment_ref.lua                     | 115 ++----
 lib/skywalking/segment_ref_test.lua                |  50 ++-
 lib/skywalking/span.lua                            |  50 +--
 lib/skywalking/span_test.lua                       |  42 +-
 lib/skywalking/tracer.lua                          |  15 +-
 lib/skywalking/tracing_context.lua                 |  16 +-
 lib/skywalking/tracing_context_test.lua            |  12 +-
 lib/skywalking/util.lua                            |  31 +-
 lib/skywalking/util_test.lua                       |   4 +-
 licenses/LICENSE-lua-resty-jit-uuid.txt            |  21 +
 skywalking-nginx-lua-2.0-0.rockspec                |  30 ++
 t/segment_ref.t                                    |  58 ++-
 t/util.t                                           |  55 +--
 test/e2e/agent-test-tools/pom.xml                  |   2 +-
 .../src/test/resources/expectedData.yaml           |   5 +-
 25 files changed, 729 insertions(+), 547 deletions(-)

diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml
index f735fe3..56c3529 100644
--- a/.github/workflows/ci.yaml
+++ b/.github/workflows/ci.yaml
@@ -31,9 +31,13 @@ jobs:
     strategy:
       fail-fast: true
     steps:
-      - uses: actions/checkout@v1
-        with:
-          submodules: true
+      - uses: actions/checkout@v2
+      # In the checkout@v2, it doesn't support git submodule. Execute the commands manually.
+      - name: checkout submodules
+        shell: bash
+        run: |
+          git submodule sync --recursive
+          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
       - uses: leafo/gh-actions-lua@v5
         with:
           luaVersion: "5.3.5"
@@ -48,6 +52,7 @@ jobs:
         run: |
           sudo luarocks install luaunit
           sudo luarocks install lua-cjson 2.1.0-1
+          sudo luarocks install lua-resty-jit-uuid
       - name: "Install OpenResty"
         run: |
           wget -qO - https://openresty.org/package/pubkey.gpg | sudo apt-key add -
diff --git a/.github/workflows/e2e.yaml b/.github/workflows/e2e.yaml
index 267edf8..9f3c447 100644
--- a/.github/workflows/e2e.yaml
+++ b/.github/workflows/e2e.yaml
@@ -31,9 +31,13 @@ jobs:
     strategy:
       fail-fast: true
     steps:
-      - uses: actions/checkout@v1
-        with:
-          submodules: true
+      - uses: actions/checkout@v2
+      # In the checkout@v2, it doesn't support git submodule. Execute the commands manually.
+      - name: checkout submodules
+        shell: bash
+        run: |
+          git submodule sync --recursive
+          git -c protocol.version=2 submodule update --init --force --recursive --depth=1
       - uses: actions/setup-java@v1
         with:
           java-version: 8
diff --git a/LICENSE b/LICENSE
index 037d158..7b2bcf4 100644
--- a/LICENSE
+++ b/LICENSE
@@ -216,7 +216,7 @@ The following components are provided under a MIT license. See project link for
 The text of each license is also included at licenses/LICENSE-[project].txt.
 
     base64 dependencies/base64.lua https://github.com/iskolbin/lbase64 MIT
-
+    lua-resty-jit-uuid lib/resty/jit-uuid.lua https://github.com/thibaultcha/lua-resty-jit-uuid MIT
 
 ========================================================================
 BSD 2-Clause License
diff --git a/README.md b/README.md
index b7dec3d..87b9ba6 100644
--- a/README.md
+++ b/README.md
@@ -71,6 +71,9 @@ http {
 # Download
 Please head to the [releases page](http://skywalking.apache.org/downloads/) to download a release of Apache SkyWalking.
 
+* 0.1.0 release requires SkyWalking 7
+* 0.2.0+ releases require SkyWalking 8
+
 # Compatible backend
 SkyWalking OAP begins to support LUA agent in 7.0.0 release. 
 
@@ -80,22 +83,22 @@ You could choose master branch before the official 7.0.0 release.
 ### Debug Startup
 By using the `/examples/nginx.conf`, you could start the Nginx with LUA module or OpenResty. Such as `nginx -c /path/to/skywalking-nginx-lua/examples/nginx.conf`
 Then you could
-1. See the `register logs` happens on the console log.
+1. See the `instance properties update logs` happens on the console log.
+```
+2020/04/04 15:15:37 [debug] 12089#1446111: *4 [lua] content_by_lua(nginx.conf:175):4: Instance report request = {"service":"User Service Name","serviceInstance":"User Service Instance Name","properties":[{"language":"Lua"}]}
+2020/04/04 15:15:37 [debug] 12089#1446111: *2 [lua] client.lua:89: reportServiceInstance(): Instance report response = {}
 ```
-2020/02/27 09:22:06 [debug] 20676#11799235: *4 [lua] content_by_lua(nginx.conf:118):4: Service register request = {"services":[{"type":"normal","serviceName":"User Service Name"}]}
-2020/02/27 09:22:06 [debug] 20676#11799235: *2 [lua] client.lua:99: registerService(): Service register response = [{"key":"User Service Name","value":1}]
 
-2020/02/27 09:22:06 [debug] 20676#11799235: *2 [lua] client.lua:106: registerService(): Service registered, service id = 1
-2020/02/27 09:22:06 [debug] 20676#11799235: *4 [lua] content_by_lua(nginx.conf:134):3: Service instance register request = {"instances":[{"time":1582766526928,"instanceUUID":"name:User Service Instance Name","properties":[{"key":"language","value":"Lua"}],"serviceId":1}]}
-2020/02/27 09:22:06 [debug] 20676#11799235: *2 [lua] client.lua:143: registerServiceInstance(): Service Instance register response = [{"key":"name:User Service Instance Name","value":1}]
-2020/02/27 09:22:06 [debug] 20676#11799235: *2 [lua] client.lua:150: registerServiceInstance(): Service Instance registered, service instance id = 1
+2. See the `heartbeat logs` happens after the `register logs`
+```
+2020/04/04 15:15:40 [debug] 12089#1446111: *4 [lua] content_by_lua(nginx.conf:188):3: KeepAlive request = {"service":"User Service Name","serviceInstance":"User Service Instance Name"}
 ```
 
-2. Access the `http://127.0.0.1:8080/ingress` then you could see the tracing happens and reported spans in the logs.
+3. Access the `http://127.0.0.1:8080/ingress` then you could see the tracing happens and reported spans in the logs.
 ```
-2020/02/27 09:22:10 [debug] 20676#11799235: *9 [lua] tracer.lua:91: prepareForReport(): segment = {"spans":[{"operationName":"\/tier2\/lb","startTime":1582766530125,"endTime":1582766530139,"spanType":"Exit","spanId":1,"isError":false,"parentSpanId":0,"componentId":6000,"peer":"User Service Name-nginx:upstream_ip:port","spanLayer":"HTTP"},{"operationName":"\/tier2\/lb","startTime":1582766530125,"tags":[{"key":"http.method","value":"GET"},{"key":"http.params","value":"http:\/\/127.0.0.1\/t [...]
-2020/02/27 09:22:10 [debug] 20676#11799235: *9 [lua] tracer.lua:95: prepareForReport(): segment buffer size = 1
-2020/02/27 09:22:10 [debug] 20676#11799235: *6 [lua] tracer.lua:91: prepareForReport(): segment = {"spans":[{"operationName":"\/ingress","startTime":1582766530114,"endTime":1582766530140,"spanType":"Exit","spanId":1,"isError":false,"parentSpanId":0,"componentId":6000,"peer":"User Service Name-nginx:upstream_ip:port","spanLayer":"HTTP"},{"operationName":"\/ingress","startTime":1582766530114,"tags":[{"key":"http.method","value":"GET"},{"key":"http.params","value":"http:\/\/127.0.0.1\/ingre [...]
+2020/04/04 15:15:46 [debug] 12089#1446111: *11 [lua] tracer.lua:83: prepareForReport(): segment = {"traceId":"1585984546953.410917649.45972","serviceInstance":"User Service Instance Name","spans":[{"operationName":"\/tier2\/lb","startTime":1585984546967,"endTime":1585984546968,"spanType":"Exit","spanId":1,"isError":false,"parentSpanId":0,"componentId":6000,"peer":"backend service","spanLayer":"Http"},{"operationName":"\/tier2\/lb","startTime":1585984546967,"tags":[{"key":"http.method","v [...]
+2020/04/04 15:15:46 [debug] 12089#1446111: *11 [lua] tracer.lua:87: prepareForReport(): segment buffer size = 1
+2020/04/04 15:15:46 [debug] 12089#1446111: *8 [lua] tracer.lua:83: prepareForReport(): segment = {"traceId":"1585984546953.410917649.45972","serviceInstance":"User Service Instance Name","spans":[{"operationName":"\/ingress","startTime":1585984546953,"endTime":1585984546968,"spanType":"Exit","spanId":1,"isError":false,"parentSpanId":0,"componentId":6000,"peer":"upstream service","spanLayer":"Http"},{"operationName":"\/ingress","startTime":1585984546953,"tags":[{"key":"http.method","value [...]
 ```
 
 ### Local Development and Unit Tests
@@ -106,6 +109,7 @@ All codes in the `lib/skywalking` require the `*_test.lua` to do the UnitTest. T
 The following libs are required in runtime or test cases, please use `LuaRocks` to install them.
 - lua-cjson. NOTICE, some platforms such as MacOS 10.15 may have issue with the latest release of this lib, consider to install an old release.(`luarocks install lua-cjson 2.1.0-1`)
 - luaunit
+- lua-resty-jit-uuid
 
 # APIs
 This LUA tracing lib is originally designed for Nginx+LUA/OpenResty ecosystems. But we write it to support more complex cases.
diff --git a/examples/nginx.conf b/examples/nginx.conf
index d5f8544..374f9ff 100644
--- a/examples/nginx.conf
+++ b/examples/nginx.conf
@@ -101,7 +101,7 @@ http {
             default_type text/html;
             content_by_lua_block {
                 ngx.say("<p>Backend service for testing only.</p>")
-                ngx.say("<p>Backend sw6 received headers: " .. ngx.req.get_headers()["sw6"] .. "</p>")
+                ngx.say("<p>Backend sw8 received headers: " .. ngx.req.get_headers()["sw8"] .. "</p>")
             }
         }
 
@@ -109,49 +109,34 @@ http {
         # ------------------------------------------------------
         # -- Mock OAP server to provide register and trace collection
         # ------------------------------------------------------
-        location /v2/service/register {
+        location /v3/management/reportProperties {
             default_type text/html;
             lua_need_request_body on;
 
             content_by_lua_block {
                 local cjson = require('cjson')
-                
-                ngx.log(ngx.DEBUG, 'Service register request = ', ngx.req.get_body_data())
-                local param = cjson.decode(ngx.req.get_body_data())
 
-                local registeredInfo = {}
-                registeredInfo[1] = {key=param.services[1].serviceName, value=1}
-                ngx.say(cjson.encode(registeredInfo))
-            }
-        }
-
-        location /v2/instance/register {
-            default_type text/html;
-            lua_need_request_body on;
+                ngx.log(ngx.DEBUG, 'Instance report request = ', ngx.req.get_body_data())
 
-            content_by_lua_block {
-                local cjson = require('cjson')
-                ngx.log(ngx.DEBUG, 'Service instance register request = ', ngx.req.get_body_data())
-                local param = cjson.decode(ngx.req.get_body_data())
-
-                local registeredInfo = {}
-
-                registeredInfo[1] = {key=param.instances[1].instanceUUID, value=1}
-                ngx.say(cjson.encode(registeredInfo))
+                local reportInfo = {}
+                ngx.say(cjson.encode(reportInfo))
             }
         }
 
-        location /v2/instance/heartbeat {
+        location /v3/management/keepAlive {
             default_type text/html;
             lua_need_request_body on;
 
             content_by_lua_block {
                 local cjson = require('cjson')
-                --ngx.log(ngx.DEBUG, 'Service instance ping request = ', ngx.req.get_body_data())
+                ngx.log(ngx.DEBUG, 'KeepAlive request = ', ngx.req.get_body_data())
+
+                local keepAliveInfo = {}
+                ngx.say(cjson.encode(keepAliveInfo))
             }
         }
 
-        location /v2/segments {
+        location /v3/segments {
             default_type text/html;
             lua_need_request_body on;
 
diff --git a/lib/skywalking/client.lua b/lib/skywalking/client.lua
index 0f0a292..09eeade 100644
--- a/lib/skywalking/client.lua
+++ b/lib/skywalking/client.lua
@@ -17,8 +17,8 @@
 
 local Client = {}
 
--- Tracing timer does the service and instance register
--- After register successfully, it sends traces and heart beat
+-- Tracing timer reports instance properties report, keeps alive and sends traces
+-- After report instance properties successfully, it sends keep alive packages.
 function Client:startBackendTimer(backend_http_uri)
     local metadata_buffer = ngx.shared.tracing_buffer
 
@@ -33,27 +33,15 @@ function Client:startBackendTimer(backend_http_uri)
 
     check = function(premature)
         if not premature then
-            local serviceId = metadata_buffer:get('serviceId')
-            if (serviceId == nil or serviceId == 0) then
-                self:registerService(metadata_buffer, backend_http_uri)
-            end
-
-            -- Register is in the async way, if register successfully, go for instance register
-            serviceId = metadata_buffer:get('serviceId')
-            if (serviceId ~= nil and serviceId ~= 0) then
-                local serviceInstId = metadata_buffer:get('serviceInstId')
-                if (serviceInstId == nil or serviceInstId == 0)  then
-                    self:registerServiceInstance(metadata_buffer, backend_http_uri)
-                end
-            end
-
-            -- After all register successfully, begin to send trace segments
-            local serviceInstId = metadata_buffer:get('serviceInstId')
-            if (serviceInstId ~= nil and serviceInstId ~= 0) then
-                self:reportTraces(metadata_buffer, backend_http_uri)
+            local instancePropertiesSubmitted = metadata_buffer:get('instancePropertiesSubmitted')
+            if (instancePropertiesSubmitted == nil or instancePropertiesSubmitted == false) then
+                self:reportServiceInstance(metadata_buffer, backend_http_uri)
+            else
                 self:ping(metadata_buffer, backend_http_uri)
             end
 
+            self:reportTraces(metadata_buffer, backend_http_uri)
+
             -- do the health check
             local ok, err = new_timer(delay, check)
             if not ok then
@@ -72,91 +60,39 @@ function Client:startBackendTimer(backend_http_uri)
     end
 end
 
--- Register service
-function Client:registerService(metadata_buffer, backend_http_uri)
+function Client:reportServiceInstance(metadata_buffer, backend_http_uri)
     local log = ngx.log
     local DEBUG = ngx.DEBUG
     local ERR = ngx.ERR
 
     local serviceName = metadata_buffer:get('serviceName')
+    local serviceInstanceName = metadata_buffer:get('serviceInstanceName')
 
     local cjson = require('cjson')
-    local serviceRegister = require("register").newServiceRegister(serviceName)
-    local serviceRegisterParam = cjson.encode(serviceRegister)
+    local reportInstance = require("management").newReportInstanceProperties(serviceName, serviceInstanceName)
+    local reportInstanceParam, err = cjson.encode(reportInstance)
+    if err then
+        log(ERR, "Request to report instance fails, ", err)
+        return
+    end
 
     local http = require('resty.http')
     local httpc = http.new()
-    local res, err = httpc:request_uri(backend_http_uri .. '/v2/service/register', {
+    local res, err = httpc:request_uri(backend_http_uri .. '/v3/management/reportProperties', {
         method = "POST",
-        body = serviceRegisterParam,
+        body = reportInstanceParam,
         headers = {
             ["Content-Type"] = "application/json",
         },
     })
 
     if not res then
-        log(ERR, "Service register fails, " .. err)
+        log(ERR, "Instance report fails, ", err)
     elseif res.status == 200 then
-        log(DEBUG, "Service register response = " .. res.body)
-        local registerResults = cjson.decode(res.body)
-
-        for i, result in ipairs(registerResults)
-        do
-            if result.key == serviceName then
-                local serviceId = result.value
-                log(DEBUG, "Service registered, service id = " .. serviceId)
-                metadata_buffer:set('serviceId', serviceId)
-            end
-        end
+        log(DEBUG, "Instance report response = ", res.body)
+        metadata_buffer:set('instancePropertiesSubmitted', true)
     else
-        log(ERR, "Service register fails, response code " .. res.status)
-    end
-end
-
--- Register service instance
-function Client:registerServiceInstance(metadata_buffer, backend_http_uri)
-    local log = ngx.log
-    local DEBUG = ngx.DEBUG
-    local ERR = ngx.ERR
-
-    local serviceInstName = 'name:' .. metadata_buffer:get('serviceInstanceName')
-    metadata_buffer:set('serviceInstanceUUID', serviceInstName)
-
-    local cjson = require('cjson')
-    local serviceInstanceRegister = require("register").newServiceInstanceRegister(
-        metadata_buffer:get('serviceId'),
-        serviceInstName,
-        ngx.now() * 1000)
-    local serviceInstanceRegisterParam = cjson.encode(serviceInstanceRegister)
-
-    local http = require('resty.http')
-    local httpc = http.new()
-    local res, err = httpc:request_uri(backend_http_uri .. '/v2/instance/register', {
-        method = "POST",
-        body = serviceInstanceRegisterParam,
-        headers = {
-            ["Content-Type"] = "application/json",
-        },
-    })
-
-    if err == nil then
-        if res.status == 200 then
-            log(DEBUG, "Service Instance register response = " .. res.body)
-            local registerResults = cjson.decode(res.body)
-
-            for i, result in ipairs(registerResults)
-            do
-                if result.key == serviceInstName then
-                    local serviceId = result.value
-                    log(DEBUG, "Service Instance registered, service instance id = " .. serviceId)
-                    metadata_buffer:set('serviceInstId', serviceId)
-                end
-            end
-        else
-            log(ERR, "Service Instance register fails, response code " .. res.status)
-        end
-    else
-        log(ERR, "Service Instance register fails, " .. err)
+        log(ERR, "Instance report fails, response code ", res.status)
     end
 end
 
@@ -166,16 +102,19 @@ function Client:ping(metadata_buffer, backend_http_uri)
     local DEBUG = ngx.DEBUG
     local ERR = ngx.ERR
 
+    local serviceName = metadata_buffer:get('serviceName')
+    local serviceInstanceName = metadata_buffer:get('serviceInstanceName')
+
     local cjson = require('cjson')
-    local pingPkg = require("register").newServiceInstancePingPkg(
-        metadata_buffer:get('serviceInstId'),
-        metadata_buffer:get('serviceInstanceUUID'),
-        ngx.now() * 1000)
-    local pingPkgParam = cjson.encode(pingPkg)
+    local pingPkg = require("management").newServiceInstancePingPkg(serviceName, serviceInstanceName)
+    local pingPkgParam, err = cjson.encode(pingPkg)
+    if err then
+        log(ERR, "Agent ping fails, ", err)
+    end
 
     local http = require('resty.http')
     local httpc = http.new()
-    local res, err = httpc:request_uri(backend_http_uri .. '/v2/instance/heartbeat', {
+    local res, err = httpc:request_uri(backend_http_uri .. '/v3/management/keepAlive', {
         method = "POST",
         body = pingPkgParam,
         headers = {
@@ -185,10 +124,10 @@ function Client:ping(metadata_buffer, backend_http_uri)
 
     if err == nil then
         if res.status ~= 200 then
-            log(ERR, "Agent ping fails, response code " .. res.status)
+            log(ERR, "Agent ping fails, response code ", res.status)
         end
     else
-        log(ERR, "Agent ping fails, " .. err)
+        log(ERR, "Agent ping fails, ", err)
     end
 end
 
@@ -208,7 +147,7 @@ function Client:reportTraces(metadata_buffer, backend_http_uri)
 
     while segment ~= nil
     do
-        local res, err = httpc:request_uri(backend_http_uri .. '/v2/segments', {
+        local res, err = httpc:request_uri(backend_http_uri .. '/v3/segments', {
             method = "POST",
             body = segment,
             headers = {
@@ -218,13 +157,13 @@ function Client:reportTraces(metadata_buffer, backend_http_uri)
 
         if err == nil then
             if res.status ~= 200 then
-                log(ERR, "Segment report fails, response code " .. res.status)
+                log(ERR, "Segment report fails, response code ", res.status)
                 break
             else
                 count = count + 1
             end
         else
-            log(ERR, "Segment report fails, " .. err)
+            log(ERR, "Segment report fails, ", err)
             break
         end
 
diff --git a/lib/skywalking/util_test.lua b/lib/skywalking/management.lua
similarity index 60%
copy from lib/skywalking/util_test.lua
copy to lib/skywalking/management.lua
index 10d8170..ccca53e 100644
--- a/lib/skywalking/util_test.lua
+++ b/lib/skywalking/management.lua
@@ -15,23 +15,27 @@
 -- limitations under the License.
 --
 
-local lu = require('luaunit')
-local Util = require('util')
+local _M = {}
 
-TestUtil = {}
-    function TestUtil.testNewID()
-        local id = Util.newID()
+-- Return Services as service register parameter
+function _M.newReportInstanceProperties(serviceName, serviceInstance)
+    local allProperties = {
+        key = "language",
+        value = "lua"
+    }
 
-        lu.assertNotNil(id[1])
-        lu.assertNotNil(id[2])
-        lu.assertNotNil(id[3])
-    end
+    return {
+        service = serviceName,
+        serviceInstance = serviceInstance,
+        properties = {allProperties}
+    }
+end
 
-    function TestUtil.testTimestamp()
-        local id = Util.timestamp()
-        lu.assertNotNil(id)
-    end
--- end TestUtil
+function _M.newServiceInstancePingPkg(serviceName, serviceInstance)
+    return {
+        service = serviceName,
+        serviceInstance = serviceInstance,
+    }
+end
 
-
-os.exit( lu.LuaUnit.run() )
+return _M
diff --git a/lib/skywalking/register.lua b/lib/skywalking/register.lua
deleted file mode 100644
index 8223ebc..0000000
--- a/lib/skywalking/register.lua
+++ /dev/null
@@ -1,66 +0,0 @@
---
--- Licensed to the Apache Software Foundation (ASF) under one or more
--- contributor license agreements.  See the NOTICE file distributed with
--- this work for additional information regarding copyright ownership.
--- The ASF licenses this file to You under the Apache License, Version 2.0
--- (the "License"); you may not use this file except in compliance with
--- the License.  You may obtain a copy of the License at
---
---    http://www.apache.org/licenses/LICENSE-2.0
---
--- Unless required by applicable law or agreed to in writing, software
--- distributed under the License is distributed on an "AS IS" BASIS,
--- WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
--- See the License for the specific language governing permissions and
--- limitations under the License.
---
-
-local _M = {}
-
--- Return Services as service register parameter
-function _M.newServiceRegister(unRegisterServiceName)
-    local serv = {
-        services = {}
-    }
-
-    local service = {
-        serviceName = unRegisterServiceName,
-        -- Field type is optional, default value is `normal`
-        type = 'normal'
-    }
-
-    serv.services[#serv.services + 1] = service
-
-    return serv
-end
-
-function _M.newServiceInstanceRegister(registeredServiceId, serviceInstUUID, registerTime)
-    local serviceInstances = {
-        instances = {}
-    }
-
-    local serviceInstance = {
-        serviceId = registeredServiceId,
-        instanceUUID = serviceInstUUID,
-        time = registerTime,
-        properties = {}
-    }
-
-    serviceInstance.properties[#serviceInstance.properties + 1] = {key = "language", value = "Lua"}
-
-    serviceInstances.instances[#serviceInstances.instances + 1] = serviceInstance
-
-    return serviceInstances
-end
-
-function _M.newServiceInstancePingPkg(registeredServiceInstId, serviceInstUUID, updateTime)
-    local serviceInstancePingPkg = {
-        serviceInstanceId = registeredServiceInstId,
-        time = updateTime,
-        serviceInstanceUUID = serviceInstUUID,
-    }
-
-    return serviceInstancePingPkg
-end
-
-return _M
diff --git a/lib/skywalking/resty/jit-uuid.lua b/lib/skywalking/resty/jit-uuid.lua
new file mode 100644
index 0000000..f101009
--- /dev/null
+++ b/lib/skywalking/resty/jit-uuid.lua
@@ -0,0 +1,425 @@
+--- jit-uuid
+-- Fast and dependency-free UUID library for LuaJIT/ngx_lua.
+-- @module jit-uuid
+-- @author Thibault Charbonnier
+-- @license MIT
+-- @release 0.0.7
+
+
+local bit = require 'bit'
+
+
+local tohex = bit.tohex
+local band = bit.band
+local bor = bit.bor
+
+
+local _M = {
+    _VERSION = '0.0.7'
+}
+
+
+----------
+-- seeding
+----------
+
+
+--- Seed the random number generator.
+-- Under the hood, this function calls `math.randomseed`.
+-- It makes sure to use the most appropriate seeding technique for
+-- the current environment, guaranteeing a unique seed.
+--
+-- To guarantee unique UUIDs, you must have correctly seeded
+-- the Lua pseudo-random generator (with `math.randomseed`).
+-- You are free to seed it any way you want, but this function
+-- can do it for you if you'd like, with some added guarantees.
+--
+-- @param[type=number] seed (Optional) A seed to use. If none given, will
+-- generate one trying to use the most appropriate technique.
+-- @treturn number `seed`: the seed given to `math.randomseed`.
+-- @usage
+-- local uuid = require 'resty.jit-uuid'
+-- uuid.seed()
+--
+-- -- in ngx_lua, seed in the init_worker context:
+-- init_worker_by_lua {
+--   local uuid = require 'resty.jit-uuid'
+--   uuid.seed()
+-- }
+function _M.seed(seed)
+    if not seed then
+        if ngx then
+            seed = ngx.time() + ngx.worker.pid()
+
+        elseif package.loaded['socket'] and package.loaded['socket'].gettime then
+            seed = package.loaded['socket'].gettime()*10000
+
+        else
+            seed = os.time()
+        end
+    end
+
+    math.randomseed(seed)
+
+    return seed
+end
+
+
+-------------
+-- validation
+-------------
+
+
+do
+    if ngx and string.find(ngx.config.nginx_configure(),'--with-pcre-jit',nil,true) then
+        local type = type
+        local re_find = ngx.re.find
+        local regex = '^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$'
+
+
+        --- Validate a string as a UUID.
+        -- To be considered valid, a UUID must be given in its canonical
+        -- form (hexadecimal digits including the hyphen characters).
+        -- This function validates UUIDs disregarding their generation algorithm,
+        -- and in a case-insensitive manner, but checks the variant field.
+        --
+        -- Use JIT PCRE if available in OpenResty or fallbacks on Lua patterns.
+        --
+        -- @param[type=string] str String to verify.
+        -- @treturn boolean `valid`: true if valid UUID, false otherwise.
+        -- @usage
+        -- local uuid = require 'resty.jit-uuid'
+        --
+        -- uuid.is_valid 'cbb297c0-a956-486d-ad1d-f9bZZZZZZZZZ' --> false
+        -- uuid.is_valid 'cbb297c0-a956-486d-dd1d-f9b42df9465a' --> false (invalid variant)
+        -- uuid.is_valid 'cbb297c0a956486dad1df9b42df9465a'     --> false (no dashes)
+        -- uuid.is_valid 'cbb297c0-a956-486d-ad1d-f9b42df9465a' --> true
+        function _M.is_valid(str)
+            -- it has proven itself efficient to first check the length with an
+            -- evenly distributed set of valid and invalid uuid lengths.
+            if type(str) ~= 'string' or #str ~= 36 then
+                return false
+            end
+
+            return re_find(str, regex, 'ioj') ~= nil
+        end
+
+    else
+        local match = string.match
+        local d = '[0-9a-fA-F]'
+        local p = '^' .. table.concat({
+            d:rep(8),
+            d:rep(4),
+            d:rep(4),
+            '[89ab]' .. d:rep(3),
+            d:rep(12)
+        }, '%-') .. '$'
+
+
+        function _M.is_valid(str)
+            if type(str) ~= 'string' or #str ~= 36 then
+                return false
+            end
+
+            return match(str, p) ~= nil
+        end
+    end
+end
+
+
+----------------
+-- v4 generation
+----------------
+
+
+do
+    local fmt = string.format
+    local random = math.random
+
+
+    --- Generate a v4 UUID.
+    -- v4 UUIDs are created from randomly generated numbers.
+    --
+    -- @treturn string `uuid`: a v4 (randomly generated) UUID.
+    -- @usage
+    -- local uuid = require 'resty.jit-uuid'
+    --
+    -- local u1 = uuid()             ---> __call metamethod
+    -- local u2 = uuid.generate_v4()
+    function _M.generate_v4()
+        return (fmt('%s%s%s%s-%s%s-%s%s-%s%s-%s%s%s%s%s%s',
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+
+            tohex(bor(band(random(0, 255), 0x0F), 0x40), 2),
+            tohex(random(0, 255), 2),
+
+            tohex(bor(band(random(0, 255), 0x3F), 0x80), 2),
+            tohex(random(0, 255), 2),
+
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2),
+            tohex(random(0, 255), 2)))
+    end
+end
+
+
+----------------
+-- v3/v5 generation
+----------------
+
+
+do
+    if ngx then
+        local ffi = require 'ffi'
+
+
+        local tonumber = tonumber
+        local assert   = assert
+        local error    = error
+        local concat   = table.concat
+        local type     = type
+        local char     = string.char
+        local fmt      = string.format
+        local sub      = string.sub
+        local gmatch   = ngx.re.gmatch
+        local sha1_bin = ngx.sha1_bin
+        local md5      = ngx.md5
+        local C        = ffi.C
+        local ffi_new  = ffi.new
+        local ffi_str  = ffi.string
+        local ffi_cast = ffi.cast
+        local new_tab
+        do
+            local ok
+            ok, new_tab = pcall(require, 'table.new')
+            if not ok then
+                new_tab = function(narr, nrec) return {} end
+            end
+        end
+
+
+        ffi.cdef [[
+            typedef unsigned char u_char;
+            typedef intptr_t ngx_int_t;
+
+            u_char * ngx_hex_dump(u_char *dst, const u_char *src, size_t len);
+            ngx_int_t ngx_hextoi(u_char *line, size_t n);
+        ]]
+
+
+        local str_type    = ffi.typeof('uint8_t[?]')
+        local u_char_type = ffi.typeof('u_char *')
+
+
+        local function bin_tohex(s)
+            local slen = #s
+            local blen = slen * 2
+            local buf = ffi_new(str_type, blen)
+
+            C.ngx_hex_dump(buf, s, slen)
+
+            return ffi_str(buf, blen)
+        end
+
+
+        local function hex_to_i(s)
+            local buf = ffi_cast(u_char_type, s)
+
+            local n = tonumber(C.ngx_hextoi(buf, #s))
+            if n == -1 then
+                error("could not convert hex to number")
+            end
+
+            return n
+        end
+
+
+        local buf = new_tab(16, 0)
+
+
+        local function factory(namespace, hash_fn)
+            if not _M.is_valid(namespace) then
+                return nil, 'namespace must be a valid UUID'
+            end
+
+            local i = 0
+            local iter, err = gmatch(namespace, [[([\da-f][\da-f])]])
+            if not iter then
+                return nil, 'could not create iter: ' .. err
+            end
+
+            while true do
+                local m, err = iter()
+                if err then
+                    return nil, err
+                end
+
+                if not m then
+                    break
+                end
+
+                i = i + 1
+                buf[i] = char(tonumber(m[0], 16))
+            end
+
+            assert(i == 16, "invalid binary namespace buffer length")
+            local ns = concat(buf)
+
+            return function(name)
+                if type(name) ~= 'string' then
+                    return nil, 'name must be a string'
+                end
+
+                local hash, ver, var = hash_fn(ns, name)
+
+                return (fmt('%s-%s-%s%s-%s%s-%s', sub(hash, 1, 8),
+                    sub(hash, 9, 12),
+                    ver,
+                    sub(hash, 15, 16),
+                    var,
+                    sub(hash, 19, 20),
+                    sub(hash, 21, 32)))
+            end
+        end
+
+
+        local function v3_hash(binary, name)
+            local hash = md5(binary .. name)
+
+            return hash,
+            tohex(bor(band(hex_to_i(sub(hash, 13, 14)), 0x0F), 0x30), 2),
+            tohex(bor(band(hex_to_i(sub(hash, 17, 18)), 0x3F), 0x80), 2)
+        end
+
+
+        local function v5_hash(binary, name)
+            local hash = bin_tohex(sha1_bin(binary .. name))
+
+            return hash,
+            tohex(bor(band(hex_to_i(sub(hash, 13, 14)), 0x0F), 0x50), 2),
+            tohex(bor(band(hex_to_i(sub(hash, 17, 18)), 0x3F), 0x80), 2)
+        end
+
+
+        --- Instanciate a v3 UUID factory.
+        -- @function factory_v3
+        -- Creates a closure generating namespaced v3 UUIDs.
+        -- @param[type=string] namespace (must be a valid UUID according to `is_valid`)
+        -- @treturn function `factory`: a v3 UUID generator.
+        -- @treturn string `err`: a string describing an error
+        -- @usage
+        -- local uuid = require 'resty.jit-uuid'
+        --
+        -- local fact = assert(uuid.factory_v3('e6ebd542-06ae-11e6-8e82-bba81706b27d'))
+        --
+        -- local u1 = fact('hello')
+        -- ---> 3db7a435-8c56-359d-a563-1b69e6802c78
+        --
+        -- local u2 = fact('foobar')
+        -- ---> e8d3eeba-7723-3b72-bbc5-8f598afa6773
+        function _M.factory_v3(namespace)
+            return factory(namespace, v3_hash)
+        end
+
+
+        --- Instanciate a v5 UUID factory.
+        -- @function factory_v5
+        -- Creates a closure generating namespaced v5 UUIDs.
+        -- @param[type=string] namespace (must be a valid UUID according to `is_valid`)
+        -- @treturn function `factory`: a v5 UUID generator.
+        -- @treturn string `err`: a string describing an error
+        -- @usage
+        -- local uuid = require 'resty.jit-uuid'
+        --
+        -- local fact = assert(uuid.factory_v5('e6ebd542-06ae-11e6-8e82-bba81706b27d'))
+        --
+        -- local u1 = fact('hello')
+        -- ---> 4850816f-1658-5890-8bfd-1ed14251f1f0
+        --
+        -- local u2 = fact('foobar')
+        -- ---> c9be99fc-326b-5066-bdba-dcd31a6d01ab
+        function _M.factory_v5(namespace)
+            return factory(namespace, v5_hash)
+        end
+
+
+        --- Generate a v3 UUID.
+        -- v3 UUIDs are created from a namespace and a name (a UUID and a string).
+        -- The same name and namespace result in the same UUID. The same name and
+        -- different namespaces result in different UUIDs, and vice-versa.
+        -- The resulting UUID is derived using MD5 hashing.
+        --
+        -- This is a sugar function which instanciates a short-lived v3 UUID factory.
+        -- It is an expensive operation, and intensive generation using the same
+        -- namespaces should prefer allocating their own long-lived factory with
+        -- `factory_v3`.
+        --
+        -- @param[type=string] namespace (must be a valid UUID according to `is_valid`)
+        -- @param[type=string] name
+        -- @treturn string `uuid`: a v3 (namespaced) UUID.
+        -- @treturn string `err`: a string describing an error
+        -- @usage
+        -- local uuid = require 'resty.jit-uuid'
+        --
+        -- local u = uuid.generate_v3('e6ebd542-06ae-11e6-8e82-bba81706b27d', 'hello')
+        -- ---> 3db7a435-8c56-359d-a563-1b69e6802c78
+        function _M.generate_v3(namespace, name)
+            local fact, err = _M.factory_v3(namespace)
+            if not fact then
+                return nil, err
+            end
+
+            return fact(name)
+        end
+
+
+        --- Generate a v5 UUID.
+        -- v5 UUIDs are created from a namespace and a name (a UUID and a string).
+        -- The same name and namespace result in the same UUID. The same name and
+        -- different namespaces result in different UUIDs, and vice-versa.
+        -- The resulting UUID is derived using SHA-1 hashing.
+        --
+        -- This is a sugar function which instanciates a short-lived v5 UUID factory.
+        -- It is an expensive operation, and intensive generation using the same
+        -- namespaces should prefer allocating their own long-lived factory with
+        -- `factory_v5`.
+        --
+        -- @param[type=string] namespace (must be a valid UUID according to `is_valid`)
+        -- @param[type=string] name
+        -- @treturn string `uuid`: a v5 (namespaced) UUID.
+        -- @treturn string `err`: a string describing an error
+        -- @usage
+        -- local uuid = require 'resty.jit-uuid'
+        --
+        -- local u = uuid.generate_v5('e6ebd542-06ae-11e6-8e82-bba81706b27d', 'hello')
+        -- ---> 4850816f-1658-5890-8bfd-1ed14251f1f0
+        function _M.generate_v5(namespace, name)
+            local fact, err = _M.factory_v5(namespace)
+            if not fact then
+                return nil, err
+            end
+
+            return fact(name)
+        end
+
+    else
+        function _M.factory_v3() error('v3 UUID generation only supported in ngx_lua', 2) end
+        function _M.generate_v3() error('v3 UUID generation only supported in ngx_lua', 2) end
+        function _M.factory_v5() error('v5 UUID generation only supported in ngx_lua', 2) end
+        function _M.generate_v5() error('v5 UUID generation only supported in ngx_lua', 2) end
+    end
+end
+
+
+return setmetatable(_M, {
+    __call = _M.generate_v4
+})
\ No newline at end of file
diff --git a/lib/skywalking/segment.lua b/lib/skywalking/segment.lua
index 7842f2c..5127b52 100644
--- a/lib/skywalking/segment.lua
+++ b/lib/skywalking/segment.lua
@@ -23,32 +23,30 @@ local _M = {}
 -- local Segment = {
 --     trace_id,
 --     segment_id,
---     service_id,
---     service_inst_id,
+--     service,
+--     service_instance,
 --     spans,
 -- }
 
 -- Due to nesting relationship inside Segment/Span/TracingContext at the runtime,
 -- SegmentProtocol is created to prepare JSON format serialization.
--- Following SkyWalking official trace protocol v2
--- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent-v2/trace.proto
+-- Following SkyWalking official trace protocol v3
+-- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/Tracing.proto
 -- local SegmentProtocol = {
---     globalTraceIds,
+--     traceId,
 --     traceSegmentId,
---     serviceId,
---     serviceInstanceId,
+--     service,
+--     serviceInstance,
 --     spans,
 -- }
 
 -- Return SegmentProtocol
 function _M.transform(segment)
     local segmentBuilder = {}
-    segmentBuilder.serviceId = segment.service_id
-    segmentBuilder.globalTraceIds = {}
-    segmentBuilder.globalTraceIds[1] = {idParts = segment.trace_id}
-    segmentBuilder.traceSegmentId = {idParts = segment.segment_id}
-    segmentBuilder.serviceId = segment.service_id
-    segmentBuilder.serviceInstanceId = segment.service_inst_id
+    segmentBuilder.traceId = segment.trace_id
+    segmentBuilder.traceSegmentId = segment.segment_id
+    segmentBuilder.service = segment.service
+    segmentBuilder.serviceInstance = segment.service_instance
 
     segmentBuilder.spans = {}
 
diff --git a/lib/skywalking/segment_ref.lua b/lib/skywalking/segment_ref.lua
index 7f85167..c680da3 100644
--- a/lib/skywalking/segment_ref.lua
+++ b/lib/skywalking/segment_ref.lua
@@ -31,59 +31,34 @@ local _M = {}
 --     trace_id,
 --     segment_id,
 --     span_id,
---     network_address,
---     network_address_id = 0,
---     entry_service_instance_id = 0,
---     parent_service_instance_id = 0,
---     entry_endpoint_name,
---     entry_endpoint_id = 0,
---     parent_endpoint_name,
---     parent_endpoint_id = 0,
+--     parent_service,
+--     parent_service_instance,
+--     parent_endpoint,
+--     address_used_at_client,
 -- }
 
 function _M.new()
     return {
         type = 'CROSS_PROCESS',
-        network_address_id = 0,
-        entry_service_instance_id = 0,
-        parent_service_instance_id = 0,
-        entry_endpoint_id = 0,
-        parent_endpoint_id = 0,
     }
 end
 
 -- Deserialize value from the propagated context and initialize the SegmentRef
-function _M.fromSW6Value(value)
+function _M.fromSW8Value(value)
     local ref = _M.new()
 
     local parts = Util.split(value, '-')
-    if #parts ~= 9 then
+    if #parts ~= 8 then
         return nil
     end
 
-    ref.trace_id = Util.formatID(decode_base64(parts[2]))
-    ref.segment_id = Util.formatID(decode_base64(parts[3]))
+    ref.trace_id = decode_base64(parts[2])
+    ref.segment_id = decode_base64(parts[3])
     ref.span_id = tonumber(parts[4])
-    ref.parent_service_instance_id = tonumber(parts[5])
-    ref.entry_service_instance_id = tonumber(parts[6])
-    local peerStr = decode_base64(parts[7])
-    if string.sub(peerStr, 1, 1) == '#' then
-        ref.network_address = string.sub(peerStr, 2)
-    else
-        ref.network_address_id = tonumber(peerStr)
-    end
-    local entryEndpointStr = decode_base64(parts[8])
-    if string.sub(entryEndpointStr, 1, 1) == '#' then
-        ref.entry_endpoint_name = string.sub(entryEndpointStr, 2)
-    else
-        ref.entry_endpoint_id = tonumber(entryEndpointStr)
-    end
-    local parentEndpointStr = decode_base64(parts[9])
-    if string.sub(parentEndpointStr, 1, 1) == '#' then
-        ref.parent_endpoint_name = string.sub(parentEndpointStr, 2)
-    else
-        ref.parent_endpoint_id = tonumber(parentEndpointStr)
-    end
+    ref.parent_service = decode_base64(parts[5])
+    ref.parent_service_instance = decode_base64(parts[6])
+    ref.parent_endpoint = decode_base64(parts[7])
+    ref.address_used_at_client = decode_base64(parts[8])
 
     return ref
 end
@@ -91,71 +66,43 @@ end
 -- Return string to represent this ref.
 function _M.serialize(ref)
     local encodedRef = '1'
-    encodedRef = encodedRef .. '-' .. encode_base64(Util.id2String(ref.trace_id))
-    encodedRef = encodedRef .. '-' .. encode_base64(Util.id2String(ref.segment_id))
-    encodedRef = encodedRef .. '-' .. ref.span_id
-    encodedRef = encodedRef .. '-' .. ref.parent_service_instance_id
-    encodedRef = encodedRef .. '-' .. ref.entry_service_instance_id
-
-    local networkAddress
-    if ref.network_address_id ~= 0 then
-        networkAddress = ref.network_address_id .. ''
-    else
-        networkAddress = '#' .. ref.network_address
-    end
-    encodedRef = encodedRef .. '-' .. encode_base64(networkAddress)
-
-    local entryEndpoint
-    if ref.entry_endpoint_id ~= 0 then
-        entryEndpoint = ref.entry_endpoint_id .. ''
-    else
-        entryEndpoint = '#' .. ref.entry_endpoint_name
-    end
-    encodedRef = encodedRef .. '-' .. encode_base64(entryEndpoint)
-
-    local parentEndpoint
-    if ref.parent_endpoint_id ~= 0 then
-        parentEndpoint = ref.parent_endpoint_id .. ''
-    else
-        parentEndpoint = '#' .. ref.parent_endpoint_name
-    end
-    encodedRef = encodedRef .. '-' .. encode_base64(parentEndpoint)
+            .. '-' .. encode_base64(ref.trace_id)
+            .. '-' .. encode_base64(ref.segment_id)
+            .. '-' .. ref.span_id
+            .. '-' .. encode_base64(ref.parent_service)
+            .. '-' .. encode_base64(ref.parent_service_instance)
+            .. '-' .. encode_base64(ref.parent_endpoint)
+            .. '-' .. encode_base64(ref.address_used_at_client)
 
     return encodedRef
 end
 
 -- Due to nesting relationship inside Segment/Span/TracingContext at the runtime,
 -- RefProtocol is created to prepare JSON format serialization.
--- Following SkyWalking official trace protocol v2
--- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent-v2/trace.proto
+-- Following SkyWalking official trace protocol v3
+-- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/Tracing.proto
 -- local RefProtocol = {
 --     -- Constant in LUA, no cross-thread
 --     refType = 'CrossProcess',
+--     traceId,
 --     parentTraceSegmentId,
 --     parentSpanId,
---     parentServiceInstanceId,
---     networkAddress,
---     networkAddressId,
---     entryServiceInstanceId,
---     entryEndpoint,
---     entryEndpointId,
+--     parentService,
+--     parentServiceInstance,
 --     parentEndpoint,
---     parentEndpointId,
+--     networkAddressUsedAtPeer,
 -- }
 -- Return RefProtocol
 function _M.transform(ref)
     local refBuilder = {}
     refBuilder.refType = 'CrossProcess'
-    refBuilder.parentTraceSegmentId = {idParts = ref.segment_id }
+    refBuilder.traceId = ref.trace_id
+    refBuilder.parentTraceSegmentId = ref.segment_id
     refBuilder.parentSpanId = ref.span_id
-    refBuilder.parentServiceInstanceId = ref.parent_service_instance_id
-    refBuilder.networkAddress = ref.network_address
-    refBuilder.networkAddressId = ref.network_address_id
-    refBuilder.entryServiceInstanceId = ref.entry_service_instance_id
-    refBuilder.entryEndpoint = ref.entry_endpoint_name
-    refBuilder.entryEndpointId = ref.entry_endpoint_id
-    refBuilder.parentEndpoint = ref.parent_endpoint_name
-    refBuilder.parentEndpointId = ref.parent_endpoint_id
+    refBuilder.parentService = ref.parent_service
+    refBuilder.parentServiceInstance = ref.parent_service_instance
+    refBuilder.parentEndpoint = ref.parent_endpoint
+    refBuilder.networkAddressUsedAtPeer = ref.address_used_at_client
     return refBuilder
 end
 
diff --git a/lib/skywalking/segment_ref_test.lua b/lib/skywalking/segment_ref_test.lua
index 72c664e..11266cc 100644
--- a/lib/skywalking/segment_ref_test.lua
+++ b/lib/skywalking/segment_ref_test.lua
@@ -22,49 +22,43 @@ local cjson = require("cjson")
 
 TestSegmentRef = {}
     -- This test is originally from ContextCarrierV2HeaderTest in the Java agent.
-    function TestSegmentRef:testFromSW6Value()
-        local ref = SegmentRef.fromSW6Value('1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz')
+    function TestSegmentRef:testFromSW8Value()
+        local ref = SegmentRef.fromSW8Value('1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=')
         lu.assertNotNil(ref)
-        lu.assertEquals(ref.trace_id, {"3", "4", "5"})
-        lu.assertEquals(ref.segment_id, {"1", "2", "3"})
+        lu.assertEquals(ref.trace_id, "3.4.5")
+        lu.assertEquals(ref.segment_id, "1.2.3")
         lu.assertEquals(ref.span_id, 4)
-        lu.assertEquals(ref.parent_service_instance_id, 1)
-        lu.assertEquals(ref.entry_service_instance_id, 1)
-        lu.assertEquals(ref.network_address, '127.0.0.1:8080')
-        lu.assertEquals(ref.network_address_id, 0)
-        lu.assertEquals(ref.entry_endpoint_name, '/portal')
-        lu.assertEquals(ref.entry_endpoint_id, 0)
-        lu.assertEquals(ref.parent_endpoint_name, nil)
-        lu.assertEquals(ref.parent_endpoint_id, 123)
+        lu.assertEquals(ref.parent_service, "service")
+        lu.assertEquals(ref.parent_service_instance, "instance")
+        lu.assertEquals(ref.parent_endpoint, '/app')
+        lu.assertEquals(ref.address_used_at_client, '127.0.0.1:8080')
 
-        ref = SegmentRef.fromSW6Value('1-My40LjU=-MS')
+        ref = SegmentRef.fromSW8Value('1-My40LjU=-MS')
         lu.assertNil(ref)
     end
 
     function TestSegmentRef:testSerialize()
         local ref = SegmentRef.new()
-        ref.trace_id = {3, 4, 5}
-        ref.segment_id = {1, 2, 3}
+        ref.trace_id = "3.4.5"
+        ref.segment_id = "1.2.3"
         ref.span_id = 4
-        ref.entry_service_instance_id = 1
-        ref.parent_service_instance_id = 1
-        ref.network_address = "127.0.0.1:8080"
-        ref.entry_endpoint_name = "/portal"
-        ref.parent_endpoint_id = 123
+        ref.parent_service = "service"
+        ref.parent_service_instance = "instance"
+        ref.parent_endpoint = "/app"
+        ref.address_used_at_client = "127.0.0.1:8080"
 
-        lu.assertEquals(SegmentRef.serialize(ref), '1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz')
+        lu.assertEquals(SegmentRef.serialize(ref), '1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=')
     end
 
     function TestSegmentRef:testTransform()
         local ref = SegmentRef.new()
-        ref.trace_id = {3, 4, 5}
-        ref.segment_id = {1, 2, 3}
+        ref.trace_id = "3.4.5"
+        ref.segment_id = "1.2.3"
         ref.span_id = 4
-        ref.entry_service_instance_id = 1
-        ref.parent_service_instance_id = 1
-        ref.network_address = "127.0.0.1:8080"
-        ref.entry_endpoint_name = "/portal"
-        ref.parent_endpoint_id = 123
+        ref.parent_service = "service"
+        ref.parent_service_instance = "instance"
+        ref.parent_endpoint = "/app"
+        ref.address_used_at_client = "127.0.0.1:8080"
 
         local refProtocol = SegmentRef.transform(ref)
         local inJSON = cjson.encode(refProtocol)
diff --git a/lib/skywalking/span.lua b/lib/skywalking/span.lua
index 6dd30ec..06b585d 100644
--- a/lib/skywalking/span.lua
+++ b/lib/skywalking/span.lua
@@ -19,7 +19,7 @@ local spanLayer = require("span_layer")
 local Util = require('util')
 local SegmentRef = require("segment_ref")
 
-local CONTEXT_CARRIER_KEY = 'sw6'
+local CONTEXT_CARRIER_KEY = 'sw8'
 
 local _M = {}
 -- local Span = {
@@ -27,7 +27,6 @@ local _M = {}
 --     parent_span_id,
 --     operation_name,
 --     tags,
---     logs,
 --     layer = spanLayer.NONE,
 --     is_entry = false,
 --     is_exit = false,
@@ -44,8 +43,8 @@ local _M = {}
 
 -- Due to nesting relationship inside Segment/Span/TracingContext at the runtime,
 -- SpanProtocol is created to prepare JSON format serialization.
--- Following SkyWalking official trace protocol v2
--- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent-v2/trace.proto
+-- Following SkyWalking official trace protocol v3
+-- https://github.com/apache/skywalking-data-collect-protocol/blob/master/language-agent/Tracing.proto
 -- local SpanProtocol = {
 --     spanId,
 --     parentSpanId,
@@ -64,7 +63,7 @@ local _M = {}
 -- }
 
 -- Create an entry span. Represent the HTTP incoming request.
--- @param contextCarrier, HTTP request header, which could carry the `sw6` context
+-- @param contextCarrier, HTTP request header, which could carry the `sw8` context
 function _M.createEntrySpan(operationName, context, parent, contextCarrier)
     local span = _M.new(operationName, context, parent)
     span.is_entry = true
@@ -72,7 +71,7 @@ function _M.createEntrySpan(operationName, context, parent, contextCarrier)
     if contextCarrier ~= nil then
         local propagatedContext = contextCarrier[CONTEXT_CARRIER_KEY]
         if propagatedContext ~= nil then
-            local ref = SegmentRef.fromSW6Value(propagatedContext)
+            local ref = SegmentRef.fromSW8Value(propagatedContext)
             if ref ~= nil then
                 -- If current trace id is generated by the context, in LUA case, mostly are yes
                 -- use the ref trace id to override it, in order to keep trace id consistently same.
@@ -97,45 +96,18 @@ function _M.createExitSpan(operationName, context, parent, peer, contextCarrier)
         injectableRef.trace_id = context.trace_id
         injectableRef.segment_id = context.segment_id
         injectableRef.span_id = span.span_id
-        -- injectableRef.network_address_id wouldn't be set. Right now, there is no network_address register mechanism
-        injectableRef.network_address = peer
-
-        local entryServiceInstanceId
-        local entryEndpointName
-        -- -1 represent the endpoint id doesn't exist, but it is a meaningful value.
-        -- Once -1 is here, the entryEndpointName will be ignored.
-        local entryEndpointId = -1
+        injectableRef.address_used_at_client = peer
+        injectableRef.parent_service = context.service
+        injectableRef.parent_service_instance = context.service_instance
 
         local firstSpan = context.internal.first_span
+        local parentEndpointName
         if context.internal.first_ref then
-            local firstRef = context.internal.first_ref
-            injectableRef.entry_service_instance_id = firstRef.entry_service_instance_id
-            entryEndpointName = firstRef.entry_endpoint_name
-            entryEndpointId = firstRef.entry_endpoint_id
-            entryServiceInstanceId = firstRef.entry_service_instance_id
+            parentEndpointName = context.internal.first_ref.entry_endpoint_name
         else
-            injectableRef.entry_service_instance_id = context.service_inst_id
-            if firstSpan.is_entry then
-                entryEndpointId = 0
-                entryEndpointName = firstSpan.operation_name
-            end
-            entryServiceInstanceId = context.service_inst_id
-        end
-
-        injectableRef.entry_service_instance_id = entryServiceInstanceId
-        injectableRef.parent_service_instance_id = context.service_inst_id
-        injectableRef.entry_endpoint_name = entryEndpointName
-        injectableRef.entry_endpoint_id = entryEndpointId
-
-        local parentEndpointName
-        local parentEndpointId = -1
-
-        if firstSpan.is_entry then
             parentEndpointName = firstSpan.operation_name
-            parentEndpointId = 0
         end
-        injectableRef.parent_endpoint_name = parentEndpointName
-        injectableRef.parent_endpoint_id = parentEndpointId
+        injectableRef.parent_endpoint = parentEndpointName
 
         contextCarrier[CONTEXT_CARRIER_KEY] = SegmentRef.serialize(injectableRef)
     end
diff --git a/lib/skywalking/span_test.lua b/lib/skywalking/span_test.lua
index 56e2fd2..01863d4 100644
--- a/lib/skywalking/span_test.lua
+++ b/lib/skywalking/span_test.lua
@@ -22,7 +22,7 @@ local SpanLayer = require("span_layer")
 
 TestSpan = {}
     function TestSpan:testNewEntry()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         lu.assertNotNil(context)
 
         local span1 = Span.createEntrySpan("operation_name", context, nil, nil)
@@ -35,11 +35,11 @@ TestSpan = {}
     end
 
     function TestSpan:testNewEntryWithContextCarrier()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         lu.assertNotNil(context)
 
         -- Typical header from the SkyWalking Java Agent test case
-        local header = {sw6='1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz'}
+        local header = {sw8='1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA='}
 
         local span1 = Span.createEntrySpan("operation_name", context, nil, header)
         lu.assertNotNil(span1)
@@ -48,25 +48,21 @@ TestSpan = {}
         lu.assertEquals(span1.layer, SpanLayer.NONE)
         local ref = span1.refs[1]
         lu.assertNotNil(ref)
-        lu.assertEquals(ref.trace_id, {"3", "4", "5"})
+        lu.assertEquals(ref.trace_id, "3.4.5")
         -- Context trace id will be overrided by the ref trace id
-        lu.assertEquals(context.trace_id, {"3", "4", "5"})
-        lu.assertEquals(ref.segment_id, {"1", "2", "3"})
+        lu.assertEquals(context.trace_id, "3.4.5")
+        lu.assertEquals(ref.segment_id, "1.2.3")
         lu.assertEquals(ref.span_id, 4)
-        lu.assertEquals(ref.parent_service_instance_id, 1)
-        lu.assertEquals(ref.entry_service_instance_id, 1)
-        lu.assertEquals(ref.network_address, '127.0.0.1:8080')
-        lu.assertEquals(ref.network_address_id, 0)
-        lu.assertEquals(ref.entry_endpoint_name, '/portal')
-        lu.assertEquals(ref.entry_endpoint_id, 0)
-        lu.assertEquals(ref.parent_endpoint_name, nil)
-        lu.assertEquals(ref.parent_endpoint_id, 123)
+        lu.assertEquals(ref.parent_service, "service")
+        lu.assertEquals(ref.parent_service_instance, "instance")
+        lu.assertEquals(ref.address_used_at_client, '127.0.0.1:8080')
+        lu.assertEquals(ref.parent_endpoint, '/app')
 
         lu.assertEquals(#(context.internal.active_spans), 1)
     end
 
     function TestSpan:testNewExit()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         lu.assertNotNil(context)
 
         local contextCarrier = {}
@@ -78,11 +74,11 @@ TestSpan = {}
         lu.assertEquals(span1.peer, '127.0.0.1:80')
 
         lu.assertEquals(#(context.internal.active_spans), 1)
-        lu.assertNotNil(contextCarrier['sw6'])
+        lu.assertNotNil(contextCarrier['sw8'])
     end
 
     function TestSpan:testNew()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         lu.assertNotNil(context)
 
         local span1 = Span.new("operation_name", context, nil)
@@ -98,7 +94,7 @@ TestSpan = {}
         lu.assertNotNil(span2.start_time)
 
         -- Use new context to check again
-        context = TC.new(1, 1)
+        context = TC.new("service", "instance")
         lu.assertNotNil(context)
 
         span1 = Span.new("operation_name", context, nil)
@@ -108,9 +104,9 @@ TestSpan = {}
     end
 
     function TestSpan:testProperties()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
 
-        local header = {sw6='1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz'}
+        local header = {sw8='1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA='}
         local span1 = Span.createEntrySpan("operation_name", context, nil, header)
         Span.start(span1, 1234567)
         lu.assertEquals(span1.start_time, 1234567)
@@ -123,13 +119,13 @@ TestSpan = {}
         lu.assertEquals(span1.tags[1].value, 'value1')
 
         lu.assertEquals(#span1.refs, 1)
-        lu.assertEquals(span1.refs[1].network_address, '127.0.0.1:8080')
+        lu.assertEquals(span1.refs[1].address_used_at_client, '127.0.0.1:8080')
     end
 
     function TestSpan:testTransform()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
 
-        local header = {sw6='1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz'}
+        local header = {sw8='1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA='}
         local span1 = Span.createEntrySpan("operation_name", context, nil, header)
         Span.start(span1, 1234567)
         Span.finish(span1, 2222222)
diff --git a/lib/skywalking/tracer.lua b/lib/skywalking/tracer.lua
index f0a1a1e..13c6571 100644
--- a/lib/skywalking/tracer.lua
+++ b/lib/skywalking/tracer.lua
@@ -25,20 +25,15 @@ function Tracer:start(upstream_name)
 
     local tracingContext
     local serviceName = metadata_buffer:get("serviceName")
-    local serviceInstId = metadata_buffer:get("serviceInstId")
-    local serviceId = metadata_buffer:get('serviceId')
-    if (serviceInstId ~= nil and serviceInstId ~= 0) then
-        tracingContext = TC.new(serviceId, serviceInstId)
-    else
-        tracingContext = TC.newNoOP()
-    end
+    local serviceInstanceName = metadata_buffer:get('serviceInstanceName')
+    tracingContext = TC.new(serviceName, serviceInstanceName)
 
     -- Constant pre-defined in SkyWalking main repo
     -- 84 represents Nginx
     local nginxComponentId = 6000
 
     local contextCarrier = {}
-    contextCarrier["sw6"] = ngx.req.get_headers()["sw6"]
+    contextCarrier["sw8"] = ngx.req.get_headers()["sw8"]
     local entrySpan = TC.createEntrySpan(tracingContext, ngx.var.uri, nil, contextCarrier)
     Span.start(entrySpan, ngx.now() * 1000)
     Span.setComponentId(entrySpan, nginxComponentId)
@@ -85,11 +80,11 @@ function Tracer:prepareForReport()
         local status, segment = TC.drainAfterFinished(ngx.ctx.tracingContext)
         if status then
             local segmentJson = require('cjson').encode(Segment.transform(segment))
-            ngx.log(ngx.DEBUG, 'segment = ' .. segmentJson)
+            ngx.log(ngx.DEBUG, 'segment = ', segmentJson)
 
             local queue = ngx.shared.tracing_buffer
             local length = queue:lpush('segment', segmentJson)
-            ngx.log(ngx.DEBUG, 'segment buffer size = ' .. queue:llen('segment'))
+            ngx.log(ngx.DEBUG, 'segment buffer size = ', queue:llen('segment'))
         end
     end
 end
diff --git a/lib/skywalking/tracing_context.lua b/lib/skywalking/tracing_context.lua
index 23ecfb0..3a0dac2 100644
--- a/lib/skywalking/tracing_context.lua
+++ b/lib/skywalking/tracing_context.lua
@@ -97,8 +97,8 @@ local _M = {}
 -- local TracingContext = {
 --     trace_id,
 --     segment_id,
---     service_id,
---     service_inst_id,
+--     service,
+--     service_instance,
 --     is_noop = false,
 --     internal,
 -- }
@@ -107,16 +107,16 @@ function _M.newNoOP()
     return {is_noop = true}
 end
 
-function _M.new(serviceId, serviceInstID)
-    if serviceInstID == nil then
+function _M.new(serviceName, serviceInstanceName)
+    if serviceInstanceName == nil or serviceName == nil then
         return _M.newNoOP()
     end
 
     local tracing_context = {}
     tracing_context.trace_id = Util.newID()
     tracing_context.segment_id = tracing_context.trace_id
-    tracing_context.service_id = serviceId
-    tracing_context.service_inst_id = serviceInstID
+    tracing_context.service = serviceName
+    tracing_context.service_instance = serviceInstanceName
     tracing_context.internal = Internal.new()
     tracing_context.internal.owner = tracing_context
     return tracing_context
@@ -160,8 +160,8 @@ function _M.drainAfterFinished(tracingContext)
         local segment = {}
         segment.trace_id = tracingContext.trace_id
         segment.segment_id = tracingContext.segment_id
-        segment.service_id = tracingContext.service_id
-        segment.service_inst_id = tracingContext.service_inst_id
+        segment.service = tracingContext.service
+        segment.service_instance = tracingContext.service_instance
         segment.spans = tracingContext.internal.finished_spans
         return true, segment
     end
diff --git a/lib/skywalking/tracing_context_test.lua b/lib/skywalking/tracing_context_test.lua
index c5d4420..3c22a48 100644
--- a/lib/skywalking/tracing_context_test.lua
+++ b/lib/skywalking/tracing_context_test.lua
@@ -22,23 +22,21 @@ local Span = require('span')
 
 TestTracingContext = {}
     function TestTracingContext:testNew()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         lu.assertNotNil(context)
-        lu.assertNotNil(context.segment_id[1])
-        lu.assertNotNil(context.segment_id[2])
-        lu.assertNotNil(context.segment_id[3])
+        lu.assertNotNil(context.segment_id)
 
         lu.assertEquals(context.trace_id, context.segment_id)
     end
 
     function TestTracingContext:testInternal_NextSpanSeqID()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
 
         lu.assertEquals(context.internal.nextSpanID(context.internal), 0)
     end
 
     function TestTracingContext:testInternal_addActive()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
 
         local mockSpan = {span_id = 0}
         context.internal.addActive(context.internal, mockSpan)
@@ -47,7 +45,7 @@ TestTracingContext = {}
     end
 
     function TestTracingContext:testSpanStack()
-        local context = TC.new(1, 1)
+        local context = TC.new("service", "instance")
         local span1 = TC.createEntrySpan(context, 'entry_op')
         local span2 = TC.createExitSpan(context, "exit_op", span1, "127.0.0.1")
 
diff --git a/lib/skywalking/util.lua b/lib/skywalking/util.lua
index 18fe0ba..b16ecf2 100644
--- a/lib/skywalking/util.lua
+++ b/lib/skywalking/util.lua
@@ -80,30 +80,23 @@ local random_seed = function ()
     return seed
 end
 
-math.randomseed(random_seed())
 
-function _M.newID()
-    return {timestamp(), math.random(0, MAX_ID_PART2), math.random(0, MAX_ID_PART3)}
-end
+math.randomseed(random_seed())
 
--- Format a trace/segment id into an array.
--- An official ID should have three parts separated by '.' and each part of it is a number
-function _M.formatID(str)
-    local regex = '.'
-    if _M.is_ngx_lua then
-        regex = [[\.]]
+local newID
+-- for Nginx Lua
+local ok, uuid = pcall(require, "resty.jit-uuid")
+if ok then
+    uuid.seed()
+    newID = function()
+        return uuid.generate_v4()
     end
-    local parts = split(str, regex)
-    if #parts ~= 3 then
-        return nil
+else
+    newID = function()
+        return timestamp() .. '.' .. math.random(0, MAX_ID_PART2) .. '.' .. math.random(0, MAX_ID_PART3)
     end
-
-    return parts
 end
 
--- @param id is an array with length = 3
-function _M.id2String(id)
-    return id[1] .. '.' .. id[2] .. '.' .. id[3]
-end
+_M.newID = newID
 
 return _M
diff --git a/lib/skywalking/util_test.lua b/lib/skywalking/util_test.lua
index 10d8170..2089fe9 100644
--- a/lib/skywalking/util_test.lua
+++ b/lib/skywalking/util_test.lua
@@ -22,9 +22,7 @@ TestUtil = {}
     function TestUtil.testNewID()
         local id = Util.newID()
 
-        lu.assertNotNil(id[1])
-        lu.assertNotNil(id[2])
-        lu.assertNotNil(id[3])
+        lu.assertNotNil(id)
     end
 
     function TestUtil.testTimestamp()
diff --git a/licenses/LICENSE-lua-resty-jit-uuid.txt b/licenses/LICENSE-lua-resty-jit-uuid.txt
new file mode 100644
index 0000000..658b3d9
--- /dev/null
+++ b/licenses/LICENSE-lua-resty-jit-uuid.txt
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2016-2019 Thibault Charbonnier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
\ No newline at end of file
diff --git a/skywalking-nginx-lua-2.0-0.rockspec b/skywalking-nginx-lua-2.0-0.rockspec
new file mode 100644
index 0000000..b44f819
--- /dev/null
+++ b/skywalking-nginx-lua-2.0-0.rockspec
@@ -0,0 +1,30 @@
+package = "skywalking-nginx-lua"
+version = "2.0-0"
+source = {
+   url = "git://github.com/apache/skywalking-nginx-lua",
+   branch = "master",
+}
+
+description = {
+   summary = "The Nginx Lua agent for Apache SkyWalking",
+   homepage = "https://github.com/apache/skywalking-nginx-lua",
+   license = "Apache License 2.0"
+}
+
+dependencies = {
+   "lua-resty-http = 0.15"
+   "lua-resty-jit-uuid = 0.0.7"
+}
+
+build = {
+   type = "builtin",
+   modules = {
+    ["skywalking.management"] = "lib/skywalking/management.lua",
+    ["skywalking.segment_ref"] = "lib/skywalking/segment_ref.lua",
+    ["skywalking.segment"] = "lib/skywalking/segment.lua",
+    ["skywalking.span_layer"] = "lib/skywalking/span_layer.lua",
+    ["skywalking.span"] = "lib/skywalking/span.lua",
+    ["skywalking.tracing_context"] = "lib/skywalking/tracing_context.lua",
+    ["skywalking.util"] = "lib/skywalking/util.lua",
+   }
+}
diff --git a/t/segment_ref.t b/t/segment_ref.t
index 8c9f76a..34b3eab 100644
--- a/t/segment_ref.t
+++ b/t/segment_ref.t
@@ -20,40 +20,32 @@ run_tests;
 
 __DATA__
 
-=== TEST 1: fromSW6Value
+=== TEST 1: fromSW8Value
 --- http_config eval: $::HttpConfig
 --- config
     location /t {
         content_by_lua_block {
             local SegmentRef = require('segment_ref')
-            local ref = SegmentRef.fromSW6Value('1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz')
+            local ref = SegmentRef.fromSW8Value('1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=')
             ngx.say(ref.trace_id)
             ngx.say(ref.segment_id)
             ngx.say(ref.span_id)
-            ngx.say(ref.parent_service_instance_id)
-            ngx.say(ref.entry_service_instance_id)
-            ngx.say(ref.network_address)
-            ngx.say(ref.network_address_id)
-            ngx.say(ref.entry_endpoint_name)
-            ngx.say(ref.entry_endpoint_id)
-            ngx.say(ref.parent_endpoint_name)
-            ngx.say(ref.parent_endpoint_id)
+            ngx.say(ref.parent_service)
+            ngx.say(ref.parent_service_instance)
+            ngx.say(ref.parent_endpoint)
+            ngx.say(ref.address_used_at_client)
         }
     }
 --- request
 GET /t
 --- response_body
-345
-123
+3.4.5
+1.2.3
 4
-1
-1
+service
+instance
+/app
 127.0.0.1:8080
-0
-/portal
-0
-nil
-123
 --- no_error_log
 [error]
 
@@ -66,21 +58,20 @@ nil
         content_by_lua_block {
             local SegmentRef = require('segment_ref')
             local ref = SegmentRef.new()
-            ref.trace_id = {3, 4, 5}
-            ref.segment_id = {1, 2, 3}
+            ref.trace_id = "3.4.5"
+            ref.segment_id = "1.2.3"
             ref.span_id = 4
-            ref.entry_service_instance_id = 1
-            ref.parent_service_instance_id = 1
-            ref.network_address = "127.0.0.1:8080"
-            ref.entry_endpoint_name = "/portal"
-            ref.parent_endpoint_id = 123
+            ref.parent_service = "service"
+            ref.parent_service_instance = "instance"
+            ref.parent_endpoint = "/app"
+            ref.address_used_at_client = "127.0.0.1:8080"
             ngx.say(SegmentRef.serialize(ref))
         }
     }
 --- request
 GET /t
 --- response_body
-1-My40LjU=-MS4yLjM=-4-1-1-IzEyNy4wLjAuMTo4MDgw-Iy9wb3J0YWw=-MTIz
+1-My40LjU=-MS4yLjM=-4-c2VydmljZQ==-aW5zdGFuY2U=-L2FwcA==-MTI3LjAuMC4xOjgwODA=
 --- no_error_log
 [error]
 
@@ -95,14 +86,13 @@ GET /t
             local cjson = require("cjson")
 
             local ref = SegmentRef.new()
-            ref.trace_id = {3, 4, 5}
-            ref.segment_id = {1, 2, 3}
+            ref.trace_id = "3.4.5"
+            ref.segment_id = "1.2.3"
             ref.span_id = 4
-            ref.entry_service_instance_id = 1
-            ref.parent_service_instance_id = 1
-            ref.network_address = "127.0.0.1:8080"
-            ref.entry_endpoint_name = "/portal"
-            ref.parent_endpoint_id = 123
+            ref.parent_service = "service"
+            ref.parent_service_instance = "instance"
+            ref.parent_endpoint = "/app"
+            ref.address_used_at_client = "127.0.0.1:8080"
 
             local refProtocol = SegmentRef.transform(ref)
             local inJSON = cjson.encode(refProtocol)
diff --git a/t/util.t b/t/util.t
index e526e4f..13208d4 100644
--- a/t/util.t
+++ b/t/util.t
@@ -51,39 +51,9 @@ true
     location /t {
         content_by_lua_block {
             local util = require('util')
-            local new_id = util.newID()
-            local regex = [[^\d+$]]
-            ngx.say(#new_id)
-            for i = 1, #new_id, 1 do
-                local m = ngx.re.match(new_id[i], regex)
-                if m and tonumber(m[0]) == new_id[i] then
-                    ngx.say(i)
-                end
-            end
-        }
-    }
---- request
-GET /t
---- response_body
-3
-1
-2
-3
---- no_error_log
-[error]
-
-
-
-=== TEST 3: id2String
---- http_config eval: $::HttpConfig
---- config
-    location /t {
-        content_by_lua_block {
-            local util = require('util')
             local id = util.newID()
-            local id_str = util.id2String(id)
-            local regex = [[^\d+\.\d+\.\d+$]]
-            local m = ngx.re.match(id_str, regex)
+            local regex = [[^[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+\-[0-9a-f]+$]]
+            local m = ngx.re.match(id, regex)
             if m then
                 ngx.say(true)
             end
@@ -95,24 +65,3 @@ GET /t
 true
 --- no_error_log
 [error]
-
-
-
-=== TEST 4: formatID
---- http_config eval: $::HttpConfig
---- config
-    location /t {
-        content_by_lua_block {
-            local util = require('util')
-            local id = util.newID()
-            local id_str = util.id2String(id)
-            local parts = util.formatID(id_str)
-            ngx.say(#parts)
-        }
-    }
---- request
-GET /t
---- response_body
-3
---- no_error_log
-[error]
diff --git a/test/e2e/agent-test-tools/pom.xml b/test/e2e/agent-test-tools/pom.xml
index 09e6280..c6efbfb 100644
--- a/test/e2e/agent-test-tools/pom.xml
+++ b/test/e2e/agent-test-tools/pom.xml
@@ -38,7 +38,7 @@
         <docker.image.name>skywalking-collector</docker.image.name>
         <docker-maven-plugin.version>0.4.13</docker-maven-plugin.version>
         <exec-maven-plugin.version>1.6.0</exec-maven-plugin.version>
-        <agent-test-tools.version>14b1499e65788d570ce5914b2ca7320cd36f961e</agent-test-tools.version>
+        <agent-test-tools.version>1f009d692b99896c08cf9f26440f92287f0364e7</agent-test-tools.version>
         <agent-test-tools.workingDirectory>${project.basedir}/target/agent-test-tools</agent-test-tools.workingDirectory>
         <agent-test-tools.repos>https://github.com/apache/skywalking-agent-test-tool.git</agent-test-tools.repos>
     </properties>
diff --git a/test/e2e/e2e-with-mock-collector/src/test/resources/expectedData.yaml b/test/e2e/e2e-with-mock-collector/src/test/resources/expectedData.yaml
index a03ec9d..49513ff 100644
--- a/test/e2e/e2e-with-mock-collector/src/test/resources/expectedData.yaml
+++ b/test/e2e/e2e-with-mock-collector/src/test/resources/expectedData.yaml
@@ -49,9 +49,10 @@ segmentItems:
             parentSpanId: -1
             componentId: 6000
             refs:
-              - {parentEndpointId: 0, entryEndpointId: 0, parentServiceInstanceId: 1, parentEndpoint: /ingress, parentTraceSegmentId: not null,
+              - {parentEndpoint: /ingress, parentTraceSegmentId: not null, refType: 'CrossProcess',
                  networkAddress: 'e2e-test-with-mock-collector:upstream_ip:port', parentSpanId: 1,
-                 entryServiceInstanceId: 1, networkAddressId: 0, entryEndpoint: /ingress}
+                 parentServiceInstance: 'e2e-test-with-mock-collector-instanceA', traceId: not null,
+                 parentService: 'e2e-test-with-mock-collector'}
             spanLayer: Http
       - segmentId: not null
         spans: