wireshark抓取dubbo调用实践

接上一篇:https://doctording.blog.csdn.net/article/details/145790590, 本文来看下dubbo的调用,对dubbo调用有一个简单的认识

目录

dubbo2协议

Dubbo 框架提供了自定义的高性能 RPC 通信协议:

  • 基于 TCP 的 Dubbo2 协议
  • 基于 HTTP/2 的 Triple 协议

Dubbo2 协议规范:https://cn.dubbo.apache.org/zh-cn/overview/reference/protocols/tcp/

dubbo2协议优缺点

AI回答如下:

在评估Dubbo2协议的优缺点时,我们需要了解Dubbo是一个高性能、轻量级的开源Java RPC框架,它主要用于构建分布式服务应用。Dubbo2是基于Apache Dubbo的最新版本,它继承了Dubbo的许多优点并引入了一些新特性。以下是一些Dubbo2协议的优缺点:

优点

  • 高性能:

Dubbo使用了Netty作为其网络通信框架,支持NIO,能够提供高性能的网络通信能力。

它支持多种序列化方式(如Java原生序列化、Kryo、FST、Hessian等),可以根据需求选择最合适的序列化方式以优化性能。

  • 灵活性:

Dubbo提供了多种配置方式(XML、注解、API等),使得服务的配置更加灵活。

支持多种负载均衡策略和集群容错机制,如随机、轮询、最少活跃调用等。

  • 易用性:

Dubbo提供了丰富的API和工具,简化了分布式服务的开发和管理。

  • 社区活跃,有大量的文档和教程支持,易于上手和学习。

  • 扩展性:

Dubbo具有良好的扩展性,可以通过SPI(Service Provider Interface)机制轻松扩展新功能。

支持服务治理,如服务注册与发现、动态路由、灰度发布等。

  • 兼容性:

Dubbo支持多种协议(Dubbo协议、HTTP、REST等),便于与现有系统集成。

与Spring框架无缝集成,便于在Spring生态系统中使用。


缺点

  • 复杂性:

Dubbo作为一个功能丰富的框架,其配置和使用可能比一些更简单的解决方案要复杂一些,特别是对于初学者。

  • 维护成本:

随着Dubbo的版本更新和新特性的引入,可能需要投入一定的时间和资源来维护和升级现有的系统。

  • 学习曲线:

对于不熟悉Dubbo及其生态系统的开发者来说,可能需要一定的时间来熟悉其工作原理和最佳实践。

  • 性能开销:

虽然Dubbo提供了高性能的网络通信,但在高并发场景下,仍然可能因为序列化/反序列化、网络IO等原因产生一定的性能开销。

  • 依赖管理:

在使用Dubbo时,可能需要管理多个依赖库和框架(如Netty、Zookeeper等),这可能会增加项目的依赖复杂度。


结论:

Dubbo2作为Dubbo的最新版本,继续保持了其高性能和灵活性的优点,同时也引入了一些新特性和改进,如更好的性能优化、更多的协议支持等。然而,它也可能带来一定的复杂性,特别是在配置和维护方面。因此,选择Dubbo2还是其他技术栈,需要根据具体项目的需求、团队的技术栈熟悉程度以及未来的可扩展性需求来综合考虑。如果你正在寻找一个高性能、灵活且易于扩展的RPC框架,Dubbo2是一个不错的选择。然而,如果你的项目对学习曲线和复杂性有较高容忍度,并且需要快速集成到现有系统中,那么它也是一个很好的选项。

wireshark支持dubbo

如下配置:

init.lua中加入dofile(DATA_DIR.."dubbo.lua")

直接全局配置目录下新建dubbo.lua文件,dubbo.lua文件内容参考:https://github.com/apache/dubbo/issues/13044, 不过是有错误的,还需改正,内容如下

lua 复制代码
local bit32 = require "bit32"
do
    local pDubbo = Proto("DUBBO", "Apache Dubbo")
    local fMagic = ProtoField.uint16("dubbo.magic", "Magic", base.HEX)
    local fReqFlag = ProtoField.bool("dubbo.isRequest", "IsRequest", base.NONE)
    local f2Way = ProtoField.bool("dubbo.isTwoWay", "IsTwoWay", base.NONE)
    local fEvent = ProtoField.bool("dubbo.event", "IsEvent", base.NONE)
    local fSerializationID = ProtoField.uint8("dubbo.serializationID", "SerializationID", base.DEC)
    local fStatus = ProtoField.uint8("dubbo.status", "Status", base.DEC)
    local fRequestID = ProtoField.uint32("dubbo.requestID", "RequestID", base.DEC)
    local fDataLength = ProtoField.uint32("dubbo.dataLength", "DataLength", base.DEC)
    local fDubboVersion = ProtoField.string("dubbo.dubboVersion", "DubboVersion", base.UNICODE)
    local fServiceName = ProtoField.string("dubbo.serviceName", "ServiceName", base.UNICODE)
    local fServiceVersion = ProtoField.string("dubbo.version", "Version", base.UNICODE)
    local fMethodName = ProtoField.string("dubbo.methodName", "MethodName", base.UNICODE)
    local fMethodParamTypes = ProtoField.string("dubbo.methodParamTypes", "MethodParamTypes", base.UNICODE)
    local fMethodArgs = ProtoField.string("dubbo.methodArguments", "MethodArguments", base.UNICODE)
    local fAttachment = ProtoField.string("dubbo.attachment", "Attachment", base.UNICODE)

    pDubbo.fields = { fMagic, fReqFlag, f2Way, fEvent, fSerializationID, fStatus, fRequestID, fDataLength, fDubboVersion, fServiceName, fServiceVersion, fMethodName, fMethodParamTypes, fMethodArgs, fAttachment }

    local data_dis = Dissector.get("data")

    local function DUBBO_dissector(buf, pkt, root)
        local function accumulateByteArray(byteArray)
            local idx = 0
            local sum = 0
            while (idx < byteArray:len())
            do
                -- (len - idx- 1) * 8
                sum = sum + bit32.lshift(byteArray:get_index(idx), (byteArray:len() - idx - 1) * 8)
                idx = idx + 1
            end
            return sum
        end

        local function bytesToString(byteArray)
            local str = ""
            local idx = 0
            while (idx < byteArray:len())
            do
                str = str .. string.char(byteArray:get_index(idx))
                idx = idx + 1
            end
            return str
        end

        local function getArrayLength(arr)
            if type(arr) ~= "table" then
                return 0
            end
            return #arr
        end

        local function resolvePart(byteArray, offset)
            -- 检查第一次调用 subset 是否会越界
            if offset > getArrayLength(byteArray) or offset + 4 - 1 > getArrayLength(byteArray) then
                print("第一次调用 subset 时越界,提前返回")
                return nil, offset
            end
            local partBytes = byteArray:subset(offset, 4)
            local partLength = accumulateByteArray(partBytes)
            local startIndex = 4 + offset
            -- 检查第二次调用 subset 是否会越界
            if startIndex > getArrayLength(byteArray) or startIndex + partLength - 1 > getArrayLength(byteArray) then
                -- 调整 partLength 以避免越界
                partLength = getArrayLength(byteArray) - startIndex + 1
                if partLength < 0 then
                    partLength = 0
                end
                print("第二次调用 subset 时越界,调整 partLength 为", partLength)
            end
            local partArray = byteArray:subset(startIndex, partLength)
            offset = offset + 4 + partLength
            return bytesToString(partArray), offset
        end

        local function substringIfNecessary(str, serializationID)
            -- fastjson2 offset 1
            if serializationID == 23
            then
                str = string.sub(str, 2, -1)
                return str
            else
                return str
            end
        end

        local buf_len = buf:len();
        if buf_len < 16 then
            return false
        end

        -- dubbo magic = 0xdabb
        local magic = buf(0, 2)
        if (magic:uint(0, 2) ~= 0xdabb)
        then
            return false
        end
        local t = root:add(pDubbo, buf)
        pkt.cols.protocol = "DUBBO"
        t:add(fMagic, magic)


        -- is dubbo
        local segment2 = buf:bytes(2, 1)
        local seg2Bytes = segment2:get_index(0)
        local reqFlag = bit32.band(seg2Bytes, 128)
        t:add(fReqFlag, reqFlag)

        local twoWay = bit32.band(seg2Bytes, 64)
        t:add(f2Way, twoWay)

        local event = bit32.band(seg2Bytes, 32)
        t:add(fEvent, event)

        local serializationID = bit32.band(seg2Bytes, 0x1F)
        t:add(fSerializationID, serializationID)

        -- requestID
        t:add(fRequestID, accumulateByteArray(buf:bytes(4, 8)))

        local dataLengthSegment = buf:bytes(12, 4)
        local dataBodyLength = accumulateByteArray(dataLengthSegment)
        t:add(fDataLength, dataBodyLength)

        local dataBodyBytes = buf:bytes(16, dataBodyLength)
        if (reqFlag ~= 0)
        then
            -- process request decode
            -- 1.dubbo version
            local offset = 0
            local dubboVersionString, offset = resolvePart(dataBodyBytes, offset)
            if dubboVersionString ~= nil then
                t:add(fDubboVersion, substringIfNecessary(dubboVersionString, serializationID))
            end
            -- t:add(fDubboVersion, substringIfNecessary(dubboVersionString, serializationID))

            --  2. ServiceName
            local serviceName, offset = resolvePart(dataBodyBytes, offset)
            if serviceName ~= nil then
                t:add(fServiceName, substringIfNecessary(serviceName, serializationID))
            end

            -- 3. ServiceVersion
            local serviceVersion, offset = resolvePart(dataBodyBytes, offset)
            if serviceVersion ~= nil then
                t:add(fServiceVersion, substringIfNecessary(serviceVersion, serializationID))
            end

            -- 4. MethodName
            local methodName, offset = resolvePart(dataBodyBytes, offset)
            if methodName ~= nil then
                t:add(fMethodName, substringIfNecessary(methodName, serializationID))
            end

        else
            --    process response decode

            -- 1. status
            t:add(fStatus, buf:bytes(3, 1):get_index(0))
        end
        return true
    end

    function pDubbo.dissector(buf, pkt, root)
        if DUBBO_dissector(buf, pkt, root) then
        else
            data_dis:call(buf, pkt, root)
        end
    end

    local tcpTable = DissectorTable.get("tcp.port")
    tcpTable:add(20881, pDubbo)

end

lua文件更新后可以让wireshark重新加载下

wireshark抓取dubbo调用

如下调用返回可以抓取到

附服务提供者:
dubbo://192.168.100.198:20881/com.example.demoapi.dubboprovider.TestService?anyhost=true&application=demoprovider&deprecated=false&dubbo=2.0.2&dynamic=true&generic=false&interface=com.example.demoapi.dubboprovider.TestService&loadbalance=random&metadata-type=remote&methods=add&pid=4237&release=2.7.8&side=provider×tamp=1740186111060

相关推荐
发仔1231 天前
Dubbo介绍及示例用法
java·dubbo
初九之潜龙勿用2 天前
文心一言4.5开源模型测评:ERNIE-4.5-0.3B超轻量模型部署指南
开源·dubbo·文心一言
FPGA之旅3 天前
FPGA从零到一实现FOC(一)之PWM模块设计
fpga开发·dubbo
微风粼粼3 天前
程序员在线接单
java·jvm·后端·python·eclipse·tomcat·dubbo
吴free4 天前
mac电脑wireshark快速实现http接口抓包
网络·测试工具·http·wireshark
没事别学JAVA4 天前
obs直播通过Wireshark获取推流码
wireshark·直播·obs
有趣的我6 天前
wireshark介绍和使用
网络·测试工具·wireshark
百度Geek说6 天前
搜索数据建设系列之数据架构重构
数据仓库·重构·架构·spark·dubbo
单线程的Daniel7 天前
Dubbo RPC 序列化问题记录
windows·rpc·dubbo
武子康7 天前
Java-63 深入浅出 分布式服务 网络通信 RPC 与 RMI 详解
java·开发语言·网络·分布式·spring·rpc·dubbo