blob: 3fd8be9b7e390fbb1df547c44a8a7136b8968fa1 [file] [log] [blame]
<!doctype html>
<html lang="en" dir="ltr" class="docs-wrapper docs-doc-page docs-version-1.8.0 plugin-docs plugin-id-default docs-doc-id-modules/tubemq/client_rpc">
<head>
<meta charset="UTF-8">
<meta name="generator" content="Docusaurus v2.3.1">
<title data-rh="true">Client RPC | Apache InLong</title><meta data-rh="true" name="viewport" content="width=device-width,initial-scale=1"><meta data-rh="true" name="twitter:card" content="summary_large_image"><meta data-rh="true" property="og:url" content="https://inlong.apache.org/docs/1.8.0/modules/tubemq/client_rpc"><meta data-rh="true" name="docusaurus_locale" content="en"><meta data-rh="true" name="docsearch:language" content="en"><meta data-rh="true" name="docusaurus_version" content="1.8.0"><meta data-rh="true" name="docusaurus_tag" content="docs-default-1.8.0"><meta data-rh="true" name="docsearch:version" content="1.8.0"><meta data-rh="true" name="docsearch:docusaurus_tag" content="docs-default-1.8.0"><meta data-rh="true" property="og:title" content="Client RPC | Apache InLong"><meta data-rh="true" name="description" content="1 General Introduction"><meta data-rh="true" property="og:description" content="1 General Introduction"><link data-rh="true" rel="icon" href="/img/logo.svg"><link data-rh="true" rel="canonical" href="https://inlong.apache.org/docs/1.8.0/modules/tubemq/client_rpc"><link data-rh="true" rel="alternate" href="https://inlong.apache.org/docs/1.8.0/modules/tubemq/client_rpc" hreflang="en"><link data-rh="true" rel="alternate" href="https://inlong.apache.org/zh-CN/docs/1.8.0/modules/tubemq/client_rpc" hreflang="zh-CN"><link data-rh="true" rel="alternate" href="https://inlong.apache.org/docs/1.8.0/modules/tubemq/client_rpc" hreflang="x-default"><link data-rh="true" rel="preconnect" href="https://YUW9QEL53E-dsn.algolia.net" crossorigin="anonymous"><link rel="alternate" type="application/rss+xml" href="/blog/rss.xml" title="Apache InLong RSS Feed">
<link rel="alternate" type="application/atom+xml" href="/blog/atom.xml" title="Apache InLong Atom Feed">
<link rel="search" type="application/opensearchdescription+xml" title="Apache InLong" href="/opensearch.xml">
<script src="https://www.apachecon.com/event-images/snippet.js" async></script><link rel="stylesheet" href="/assets/css/styles.c64edd51.css">
<link rel="preload" href="/assets/js/runtime~main.63c98e82.js" as="script">
<link rel="preload" href="/assets/js/main.070aef2a.js" as="script">
</head>
<body class="navigation-with-keyboard">
<script>!function(){function e(e){document.documentElement.setAttribute("data-theme",e)}var t=function(){var e=null;try{e=localStorage.getItem("theme")}catch(e){}return e}();null!==t?e(t):window.matchMedia("(prefers-color-scheme: dark)").matches?e("dark"):(window.matchMedia("(prefers-color-scheme: light)").matches,e("light"))}()</script><div id="__docusaurus">
<div role="region" aria-label="Skip to main content"><a class="skipToContent_fXgn" href="#docusaurus_skipToContent_fallback">Skip to main content</a></div><nav aria-label="Main" class="navbar navbar--fixed-top"><div class="navbar__inner"><div class="navbar__items"><button aria-label="Toggle navigation bar" aria-expanded="false" class="navbar__toggle clean-btn" type="button"><svg width="30" height="30" viewBox="0 0 30 30" aria-hidden="true"><path stroke="currentColor" stroke-linecap="round" stroke-miterlimit="10" stroke-width="2" d="M4 7h22M4 15h22M4 23h22"></path></svg></button><a class="navbar__brand" href="/"><div class="navbar__logo"><img src="/img/logo.svg" alt="Apache" class="themedImage_ToTc themedImage--light_HNdA"><img src="/img/logo.svg" alt="Apache" class="themedImage_ToTc themedImage--dark_i4oU"></div><b class="navbar__title text--truncate">Apache InLong</b></a></div><div class="navbar__items navbar__items--right"><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a class="navbar__link" aria-haspopup="true" aria-expanded="false" role="button" href="/docs/introduction">Docs</a><ul class="dropdown__menu"><li><a class="dropdown__link" href="/docs/next/introduction">Next</a></li><li><a class="dropdown__link" href="/docs/introduction">1.11.0</a></li><li><a class="dropdown__link" href="/docs/1.10.0/introduction">1.10.0</a></li><li><a class="dropdown__link" href="/docs/1.9.0/introduction">1.9.0</a></li><li><a class="dropdown__link" href="/docs/1.8.0/introduction">1.8.0</a></li><li><a class="dropdown__link" href="/versions/">All versions</a></li></ul></div><a class="navbar__item navbar__link" href="/downloads">Download</a><a class="navbar__item navbar__link" href="/community/how-to-contribute">Community</a><a class="navbar__item navbar__link" href="/blog">Blog</a><a class="navbar__item navbar__link" href="/team">Team</a><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href="#" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link">ASF</a><ul class="dropdown__menu"><li><a href="https://www.apache.org/" target="_blank" rel="noopener noreferrer" class="dropdown__link">Apache Software Foundation</a></li><li><a href="https://www.apache.org/licenses/" target="_blank" rel="noopener noreferrer" class="dropdown__link">License</a></li><li><a href="https://www.apache.org/events/current-event" target="_blank" rel="noopener noreferrer" class="dropdown__link">Events</a></li><li><a href="https://www.apache.org/security/" target="_blank" rel="noopener noreferrer" class="dropdown__link">Security</a></li><li><a href="https://www.apache.org/foundation/sponsorship.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Sponsorship</a></li><li><a href="https://www.apache.org/foundation/policies/privacy.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Privacy</a></li><li><a href="https://www.apache.org/foundation/thanks.html" target="_blank" rel="noopener noreferrer" class="dropdown__link">Thanks</a></li></ul></div><div class="navbar__item dropdown dropdown--hoverable dropdown--right"><a href="#" aria-haspopup="true" aria-expanded="false" role="button" class="navbar__link"><svg viewBox="0 0 24 24" width="20" height="20" aria-hidden="true" class="iconLanguage_nlXk"><path fill="currentColor" d="M12.87 15.07l-2.54-2.51.03-.03c1.74-1.94 2.98-4.17 3.71-6.53H17V4h-7V2H8v2H1v1.99h11.17C11.5 7.92 10.44 9.75 9 11.35 8.07 10.32 7.3 9.19 6.69 8h-2c.73 1.63 1.73 3.17 2.98 4.56l-5.09 5.02L4 19l5-5 3.11 3.11.76-2.04zM18.5 10h-2L12 22h2l1.12-3h4.75L21 22h2l-4.5-12zm-2.62 7l1.62-4.33L19.12 17h-3.24z"></path></svg>English</a><ul class="dropdown__menu"><li><a href="/docs/1.8.0/modules/tubemq/client_rpc" target="_self" rel="noopener noreferrer" class="dropdown__link dropdown__link--active" lang="en">English</a></li><li><a href="/zh-CN/docs/1.8.0/modules/tubemq/client_rpc" target="_self" rel="noopener noreferrer" class="dropdown__link" lang="zh-CN">简体中文</a></li></ul></div><a href="https://github.com/apache/inlong" target="_blank" rel="noopener noreferrer" class="navbar__item navbar__link">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a><div class="toggle_vylO colorModeToggle_DEke"><button class="clean-btn toggleButton_gllP toggleButtonDisabled_aARS" type="button" disabled="" title="Switch between dark and light mode (currently light mode)" aria-label="Switch between dark and light mode (currently light mode)" aria-live="polite"><svg viewBox="0 0 24 24" width="24" height="24" class="lightToggleIcon_pyhR"><path fill="currentColor" d="M12,9c1.65,0,3,1.35,3,3s-1.35,3-3,3s-3-1.35-3-3S10.35,9,12,9 M12,7c-2.76,0-5,2.24-5,5s2.24,5,5,5s5-2.24,5-5 S14.76,7,12,7L12,7z M2,13l2,0c0.55,0,1-0.45,1-1s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S1.45,13,2,13z M20,13l2,0c0.55,0,1-0.45,1-1 s-0.45-1-1-1l-2,0c-0.55,0-1,0.45-1,1S19.45,13,20,13z M11,2v2c0,0.55,0.45,1,1,1s1-0.45,1-1V2c0-0.55-0.45-1-1-1S11,1.45,11,2z M11,20v2c0,0.55,0.45,1,1,1s1-0.45,1-1v-2c0-0.55-0.45-1-1-1C11.45,19,11,19.45,11,20z M5.99,4.58c-0.39-0.39-1.03-0.39-1.41,0 c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0s0.39-1.03,0-1.41L5.99,4.58z M18.36,16.95 c-0.39-0.39-1.03-0.39-1.41,0c-0.39,0.39-0.39,1.03,0,1.41l1.06,1.06c0.39,0.39,1.03,0.39,1.41,0c0.39-0.39,0.39-1.03,0-1.41 L18.36,16.95z M19.42,5.99c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06c-0.39,0.39-0.39,1.03,0,1.41 s1.03,0.39,1.41,0L19.42,5.99z M7.05,18.36c0.39-0.39,0.39-1.03,0-1.41c-0.39-0.39-1.03-0.39-1.41,0l-1.06,1.06 c-0.39,0.39-0.39,1.03,0,1.41s1.03,0.39,1.41,0L7.05,18.36z"></path></svg><svg viewBox="0 0 24 24" width="24" height="24" class="darkToggleIcon_wfgR"><path fill="currentColor" d="M9.37,5.51C9.19,6.15,9.1,6.82,9.1,7.5c0,4.08,3.32,7.4,7.4,7.4c0.68,0,1.35-0.09,1.99-0.27C17.45,17.19,14.93,19,12,19 c-3.86,0-7-3.14-7-7C5,9.07,6.81,6.55,9.37,5.51z M12,3c-4.97,0-9,4.03-9,9s4.03,9,9,9s9-4.03,9-9c0-0.46-0.04-0.92-0.1-1.36 c-0.98,1.37-2.58,2.26-4.4,2.26c-2.98,0-5.4-2.42-5.4-5.4c0-1.81,0.89-3.42,2.26-4.4C12.92,3.04,12.46,3,12,3L12,3z"></path></svg></button></div><div class="searchBox_ZlJk"><button type="button" class="DocSearch DocSearch-Button" aria-label="Search"><span class="DocSearch-Button-Container"><svg width="20" height="20" class="DocSearch-Search-Icon" viewBox="0 0 20 20"><path d="M14.386 14.386l4.0877 4.0877-4.0877-4.0877c-2.9418 2.9419-7.7115 2.9419-10.6533 0-2.9419-2.9418-2.9419-7.7115 0-10.6533 2.9418-2.9419 7.7115-2.9419 10.6533 0 2.9419 2.9418 2.9419 7.7115 0 10.6533z" stroke="currentColor" fill="none" fill-rule="evenodd" stroke-linecap="round" stroke-linejoin="round"></path></svg><span class="DocSearch-Button-Placeholder">Search</span></span><span class="DocSearch-Button-Keys"></span></button></div></div></div><div role="presentation" class="navbar-sidebar__backdrop"></div></nav><div id="docusaurus_skipToContent_fallback" class="main-wrapper mainWrapper_z2l0 docsWrapper_BCFX"><button aria-label="Scroll back to top" class="clean-btn theme-back-to-top-button backToTopButton_sjWU" type="button"></button><div class="docPage__5DB"><aside class="theme-doc-sidebar-container docSidebarContainer_b6E3"><div class="sidebarViewport_Xe31"><div class="sidebar_njMd"><nav aria-label="Docs sidebar" class="menu thin-scrollbar menu_SIkG"><ul class="theme-doc-sidebar-menu menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/1.8.0/introduction">Introduction</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/design_and_concept/basic_concept">Design and Concept</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/quick_start/how_to_build">Quick Start</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/deployment/standalone">Deployment</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" aria-expanded="true" href="/docs/1.8.0/modules/agent/overview">Components</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/agent/overview">Agent</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/dataproxy/overview">DataProxy</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret menu__link--active" aria-expanded="true" tabindex="0" href="/docs/1.8.0/modules/tubemq/overview">TubeMQ</a></div><ul style="display:block;overflow:visible;height:auto" class="menu__list"><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/overview">Overview</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/quick_start">Quick Start</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/producer_example">Producer Example</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/consumer_example">Consumer Example</a></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-3 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/tubemq/tubemq-manager/overview">tubemq-manager</a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/client_partition_assign_introduction">client partition assign</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link menu__link--active" aria-current="page" tabindex="0" href="/docs/1.8.0/modules/tubemq/client_rpc">Client RPC</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/clients_java">TubeMQ JAVA SDK API</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/configure_introduction">Configuration</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/console_introduction">Console Introduction</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/error_code">Error Code</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/http_access_api">HTTP API</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/tubemq_metrics">TubeMQ Metrics</a></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-3 menu__list-item"><a class="menu__link" tabindex="0" href="/docs/1.8.0/modules/tubemq/tubemq_perf_test_vs_Kafka">TubeMQ VS Kafka</a></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/sort/overview">Sort</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/manager/overview">Manager</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/dashboard/overview">Dashboard</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/sort-standalone/overview">Sort Standalone</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-2 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" tabindex="0" href="/docs/1.8.0/modules/audit/overview">Audit</a></div></li></ul></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/data_node/extract_node/overview">Data Nodes</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/sdk/dataproxy-sdk/cpp">SDK</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/user_guide/dashboard_usage">User Guide</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/development/inlong_msg">Development</a></div></li><li class="theme-doc-sidebar-item-category theme-doc-sidebar-item-category-level-1 menu__list-item menu__list-item--collapsed"><div class="menu__list-item-collapsible"><a class="menu__link menu__link--sublist menu__link--sublist-caret" aria-expanded="false" href="/docs/1.8.0/administration/user_management">Administration</a></div></li><li class="theme-doc-sidebar-item-link theme-doc-sidebar-item-link-level-1 menu__list-item"><a class="menu__link" href="/docs/1.8.0/contact">Contact Us</a></li></ul></nav></div></div></aside><main class="docMainContainer_gTbr"><div class="container padding-top--md padding-bottom--lg"><div class="row"><div class="col docItemCol_VOVn"><div class="theme-doc-version-banner alert alert--warning margin-bottom--md" role="alert"><div>This is documentation for <!-- -->Apache InLong<!-- --> <b>1.8.0</b>, which is no longer actively maintained.</div><div class="margin-top--md">For up-to-date documentation, see the <b><a href="/docs/modules/tubemq/client_rpc">latest version</a></b> (<!-- -->1.11.0<!-- -->).</div></div><div class="docItemContainer_Djhp"><article><nav class="theme-doc-breadcrumbs breadcrumbsContainer_Z_bl" aria-label="Breadcrumbs"><ul class="breadcrumbs" itemscope="" itemtype="https://schema.org/BreadcrumbList"><li class="breadcrumbs__item"><a aria-label="Home page" class="breadcrumbs__link" href="/"><svg viewBox="0 0 24 24" class="breadcrumbHomeIcon_YNFT"><path d="M10 19v-5h4v5c0 .55.45 1 1 1h3c.55 0 1-.45 1-1v-7h1.7c.46 0 .68-.57.33-.87L12.67 3.6c-.38-.34-.96-.34-1.34 0l-8.36 7.53c-.34.3-.13.87.33.87H5v7c0 .55.45 1 1 1h3c.55 0 1-.45 1-1z" fill="currentColor"></path></svg></a></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">Components</span><meta itemprop="position" content="1"></li><li class="breadcrumbs__item"><span class="breadcrumbs__link">TubeMQ</span><meta itemprop="position" content="2"></li><li itemscope="" itemprop="itemListElement" itemtype="https://schema.org/ListItem" class="breadcrumbs__item breadcrumbs__item--active"><span class="breadcrumbs__link" itemprop="name">Client RPC</span><meta itemprop="position" content="3"></li></ul></nav><span class="theme-doc-version-badge badge badge--secondary">Version: 1.8.0</span><div class="tocCollapsible_ETCw theme-doc-toc-mobile tocMobile_ITEo"><button type="button" class="clean-btn tocCollapsibleButton_TO0P">On this page</button></div><div class="theme-doc-markdown markdown"><header><h1>Client RPC</h1></header><h2 class="anchor anchorWithStickyNavbar_LWe7" id="1-general-introduction">1 General Introduction<a href="#1-general-introduction" class="hash-link" aria-label="Direct link to 1 General Introduction" title="Direct link to 1 General Introduction"></a></h2><p>Implements of this part can be found in <code>org.apache.tubemq.corerpc</code>. Each node in Apache TubeMQ Cluster Communicates by TCP Keep-Alive. Mseeages are definded using binary and protobuf combined.
<img loading="lazy" src="/assets/images/rpc_bytes_def-c8c63b21ec5ea017431db345384baa2d.png" width="1049" height="614" class="img_ev3q"></p><p>All we can see in TCP are binary streams. We defined:</p><ul><li>msgToken: 4-bytes, <code>RPC_PROTOCOL_BEGIN_TOKEN</code> in header, which are used to distinguish each message and identify the legitimacy of the counterpart. When message client received is not started with this header field, client needs to close the connection and prompt the error and quit or reconnect because the protocal is not supported by TubeMQ or something wrong may happended. </li><li>serialNo: 4-bytes, this field is sent by client to server and returned by server exactly the same when after handling the request. It is mainly used to associate the context of the client request and response. </li><li>listSize: 4-bytes, the length of the following PB blocks, this field would not be 0 in current definition.</li><li><code>[&lt;len&gt;&lt;data&gt;]</code>: field is a combination of 2 fields<ul><li>len: the length of data</li><li>data: the content of data</li></ul></li></ul><blockquote><p>Why the format of <code>listSize [&lt;len&gt;&lt;data&gt;]</code> ?</p><p>This is because the serialized PB data is saved as a ByteBuffer object in TubeMQ, and in Java, there a maximum(8196) length of ByteBuffer block, an over length PB message needs to be saved in several ByteBuffer. No total length was counted now, and the ByteBuffer is directly written when Serializing in to TCP message.</p><p><strong>Please pay attention when implementing multiple languages and SDKs.</strong> Need to serialize PB data content into arrays of blocks(supported in PB codecs).</p></blockquote><h2 class="anchor anchorWithStickyNavbar_LWe7" id="2-pb-format-code">2 PB format code:<a href="#2-pb-format-code" class="hash-link" aria-label="Direct link to 2 PB format code:" title="Direct link to 2 PB format code:"></a></h2><p>There mainly has three kinds of PB messages in TubeMQ:</p><ul><li>RPC related messages : <code>RPC.proto</code></li><li>Master related messages : <code>MasterService.proto</code></li><li>Broker related messages : <code>BrokerService.proto</code></li></ul><p><code>RPC.proto</code> defines 6 struct, which divided into 2 class: Request message and Response message. Response message is divided into Successful Response and Exception Response.</p><p>The request message encoding and response message decoding can be implemented in the <code>NettyClient.java</code> class. There is some room for improvement in this part of the definition and can be found in <a href="https://issues.apache.org/jira/browse/TUBEMQ-109" target="_blank" rel="noopener noreferrer">TUBEMQ-109</a>. However, due to compatibility concerns, it will be gradually replaced. We have implemented the current protobuf version, which is not a problem until at least 1.0.0. With the new protocol, the protocol implementation module requires each SDK to allow room for improvement. Take request message as an example, <code>RpcConnHeader</code> and other related structures are as follows:</p><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message RpcConnHeader {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 flag = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 traceId = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 spanId = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 parentId = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message RequestHeader {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int32 serviceType = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int32 protocolVer = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message RequestBody {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 method = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 timeout = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional bytes request = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Flag marks whether the message is requested or not, and the next three marks represent the content of the message trace, which is not currently used; the related is a fixed mapping of the service type, protocol version, service type, etc., the more critical parameter RequestBody.timeout is the maximum allowable time from when a request is received by the server to when it is actually processed. Long wait time, discarded if exceeded, current default is 10 seconds, request filled as follows.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">RequestWrapper requestWrapper =</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> new RequestWrapper(PbEnDecoder.getServiceIdByServiceName(targetInterface),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> RpcProtocol.RPC_PROTOCOL_VERSION,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> RpcConstants.RPC_FLAG_MSG_TYPE_REQUEST,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> requestTimeout); // request timeout</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><h2 class="anchor anchorWithStickyNavbar_LWe7" id="3-interactive-diagram-of-the-clients-pb-request--response">3 Interactive diagram of the client&#x27;s PB request &amp; response:<a href="#3-interactive-diagram-of-the-clients-pb-request--response" class="hash-link" aria-label="Direct link to 3 Interactive diagram of the client&#x27;s PB request &amp; response:" title="Direct link to 3 Interactive diagram of the client&#x27;s PB request &amp; response:"></a></h2><p><strong>Producer Interaction</strong></p><p>The Producer has four pairs of instructions in the system, registration to master, heartbeat to master, exit from master and sending message to brokers.
<img loading="lazy" src="/assets/images/rpc_producer_diagram-ed4bb00e58a1ecec65f60f7c921b538c.png" width="974" height="694" class="img_ev3q"></p><p>Here we can see, Producer&#x27;s implementation logic is to get metadata such as the list of partitions of specified topic from master, then select a partition and send message via TCP connection according to the rules of the client. It may be unsafe to send message without registration to master, the initial consideration was to use internal intake messages as much as possible and after that, considering security issues, we added authorization information carrying on top of this to perform authentication and authorization checks on the server side, solving the situation where the client bypasses the direct connection to the master and sends messages without authorization. But this will only enable in production environment.</p><p><strong>Note in producer side of multiple languages implementation:</strong></p><ol><li><p>Our Master is running as a hot-swap master, and the switchover is based on the information carried by the <code>RspExceptionBody</code>. In this case, you need to search for the keywords <code>&amp;quot;StandbyException&amp;quot;</code>, If this type of exception occurs, switch to another Master node for re-registration. This part has some relevant issues to adjust to the problem.</p></li><li><p>Producer should re-register in the event of a Master connection failure during production, e.g. timeout, passive connection break, etc.</p></li><li><p>Producer side should pay attention to the Broker pre-connection operation in advance: the back-end cluster can have hundreds of Broker nodes, and each Broker has about ten partitions, so there will be thousands of possible records about the partition, after the SDK receives the metadata information from the Master, it should perform the connection establishment operation on the Broker that has not yet built the chain in advance.</p></li><li><p>The Producer to Broker connection should be aware of anomaly detection and should be able to detect Broker bad spots and long periods of no messages, and to recycle the connection to Broker to avoid unstable operation in long-term running scene.</p></li></ol><p><strong>Consumer Interaction Diagram</strong>:</p><p>Consumer has 7 pairs of command in all, Register, Heartbeat, Exit to Master; Register, Logout, Heartbeat, Pulling mseeage to Broker. Registration and Logout to Broker is the same command, indicated by a different status code.</p><p><img loading="lazy" src="/assets/images/rpc_consumer_diagram-048bd92863ee20cdf21f684cef98258f.png" width="990" height="694" class="img_ev3q"></p><p>As we can see from the above picture, the Consumer first has to register to the Master, but registering to the Master can not get Metadata information immediately because TubeMQ is using a server-side load-balancing model, and the client needs to wait for the server to dispatch the consumption partition information; Consumer to Broker needs to register the logout operation. Partition is exclusive at the time of consumption, i.e., the same partition can only be consumed by one consumer in the same group at the same time. To solve this problem, the client needs to register and get consumption access to the partition; message pull and consumption confirmation need to appear in pairs. Although the protocol supports multiple pulls and then the last acknowledgement process, it is possible that the consumer permissions of a partition may be lost timeout from the client, thus This causes the data rollback to be triggered by repetitive consumption, and the more data is saved the more repetitive consumption will occur, so follow the 1:1 submission comparison fit.</p><h2 class="anchor anchorWithStickyNavbar_LWe7" id="4-client-feature">4 Client feature:<a href="#4-client-feature" class="hash-link" aria-label="Direct link to 4 Client feature:" title="Direct link to 4 Client feature:"></a></h2><table><thead><tr><th><strong>FEATURE</strong></th><th><strong>Java</strong></th><th><strong>C/C++</strong></th><th><strong>Go</strong></th><th><strong>Python</strong></th><th><strong>Rust</strong></th><th><strong>NOTE</strong></th></tr></thead><tbody><tr><td>TLS</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Authorization</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Anti-bypass-master production/consumption</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Distributed system with clients accessing Broker without Master&#x27;s authentication authorization</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Effectively-Once</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Partition offset consumption</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Multiple Topic Consumption for a single Consumer group</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Server Consumption filter</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Auto shielding inactive Nodes</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Auto shielding bad Brokers</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Auto reconnect</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Auto recycling of Idle Connection</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Inactive for more than a specified period(e.g. 3min, mainly the producer side)</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Connection reuse</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Connection sharing according to the sessionFactory</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Unconnection reuse</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Asynchrounous Production</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Synchrounous Production</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Pull Consumption</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Push Consumption</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Consumption limit (QOS)</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Limit the amount of data per unit of time consumed by consumers</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Pull Consumption frequency limit</td><td></td><td></td><td></td><td></td><td></td><td></td></tr><tr><td>Consumer Pull Consumption frequency limit</td><td></td><td></td><td></td><td></td><td></td><td></td></tr></tbody></table><h2 class="anchor anchorWithStickyNavbar_LWe7" id="5-client-function-induction-casebycase">5 Client function Induction CaseByCase:<a href="#5-client-function-induction-casebycase" class="hash-link" aria-label="Direct link to 5 Client function Induction CaseByCase:" title="Direct link to 5 Client function Induction CaseByCase:"></a></h2><p><strong>Client side and server side RPC interaction process</strong></p><hr><p><img loading="lazy" src="/assets/images/rpc_inner_structure-3438098f8c404d1bbf3876abb80db693.png" width="729" height="449" class="img_ev3q"></p><p>As shown above, the client has to maintain local preservation of the sent request message until the RPC times out, or a response message is received and the response The message is associated by the SerialNo generated when the request is sent; the Broker information received from the server side, and the Topic information, which the SDK stores locally and updates with the latest returned information, as well as periodic reports to the Server side; the SDK is maintained to the heartbeat of the Master or Broker, and if Master feedback is found When the registration timeout error, re-registration operation should be carried out; SDK should be based on Broker connection establishment, the same process different Between objects, to allow the business to choose whether to support per-object or per-process connections.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="51-message-producer-register-to-master">5.1 Message: Producer register to Master:<a href="#51-message-producer-register-to-master" class="hash-link" aria-label="Direct link to 5.1 Message: Producer register to Master:" title="Direct link to 5.1 Message: Producer register to Master:"></a></h3><hr><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message RegisterRequestP2M {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string clientId = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string topicList = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int64 brokerCheckSum = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string hostName = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional MasterCertificateInfo authInfo = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional string jdkVersion = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional ApprovedClientConfig appdConfig = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message RegisterResponseM2P {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 errCode = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string errMsg = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int64 brokerCheckSum = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string brokerInfos = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional MasterAuthorizedInfo authorizedInfo = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional ApprovedClientConfig appdConfig = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>ClientId</strong>:Producer needs to construct a ClientId at startup, and the current construction rule is: </p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">ClientId = consumerGroup + &quot;_&quot;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + AddressUtils.getLocalAddress() + &quot;_&quot; // local ip (IPV4)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + pid + &quot;_&quot; // processId</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + timestamp + &quot;_&quot; // timestamp</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + counter + &quot;_&quot; // increament counter</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + consumerType + &quot;_&quot; // type of consumer,including Pull and Push </span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> + clientVersion; // version for client</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>it is recommended that other languages add the above markup for easier access to the issue Exclusion. The ID value is valid for the lifetime of the Producer.</p><p><strong>TopicList</strong>: The list of topics published by the user, Producer provides the initial list of topics for the data to be published at initialization, and also allows the business to defer adding new topics via the publish function in runtime, but does not support reducing topics in runtime.</p><p><strong>brokerCheckSum</strong>: The check value of the Broker metadata information stored locally by the client, which is not available locally in Producer at initial startup, takes the value as -1; the SDK needs to carry the last BrokerCheckSum value on each request, and the Master determines whether the client&#x27;s metadata needs to be updated by comparing the value.</p><p><strong>hostname</strong>: The IPV4 address value of the machine where the Producer is located.</p><p><strong>success</strong>: Whether the operation is successful, success is true, failure is false.</p><p><strong>errCode</strong>: The code of error, currently one error code represents a large class of error, the specific cause of the error needs to be specifically identified by <code>errMsg</code>.</p><p><strong>errMsg</strong>: The specific error message that the SDK needs to print out if something goes wrong.</p><p><strong>authInfo</strong>:Authentication authorization information, if the user configuration is filled in to start authentication processing, then fill in; if authentication is required, then report according to the signature of the user name and password; if it is running, such as heartbeat, if the Master forces authentication processing, then report according to the signature of the user name and password; if not, then authenticate according to the authorization Token provided by the Master during the previous interaction; this authorization Token is also used to carry the message to Broker during production.</p><p><strong>brokerInfos</strong>: Broker metadata information, which is primarily a list of Broker information for the entire cluster that the Master feeds back to the Producer in this field; the format is as follows.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">public BrokerInfo(String strBrokerInfo, int brokerPort) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> String[] strBrokers =</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> strBrokerInfo.split(TokenConstants.ATTR_SEP);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> this.brokerId = Integer.parseInt(strBrokers[0]);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> this.host = strBrokers[1];</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> this.port = brokerPort;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (!TStringUtils.isBlank(strBrokers[2])) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> this.port = Integer.parseInt(strBrokers[2]);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> this.buildStrInfo();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>authorizedInfo</strong>: Master provides authorization information in the following format.</p><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message MasterAuthorizedInfo {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int64 visitAuthorizedToken = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional string authAuthorizedToken = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>visitAuthorizedToken</strong>: To prevent clients from bypassing the Master&#x27;s access authorization token, if that data is available, the SDK should save it locally and carry that information on subsequent visits to the Broker; if the field is changed on subsequent heartbeats, the locally cached data for that field needs to be updated.</p><p><strong>authAuthorizedToken</strong>:Authenticated authorization tokens, if they have data for that field, they need to save and carry that field information for subsequent accesses to the Master and Broker; if the field is changed on subsequent heartbeats, the local cache of that field data needs to be updated.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="52-mseeage-heartbeat-from-producer-to-master">5.2 Mseeage: Heartbeat from Producer to Master:<a href="#52-mseeage-heartbeat-from-producer-to-master" class="hash-link" aria-label="Direct link to 5.2 Mseeage: Heartbeat from Producer to Master:" title="Direct link to 5.2 Mseeage: Heartbeat from Producer to Master:"></a></h3><hr><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message HeartRequestP2M {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string clientId = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int64 brokerCheckSum = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string hostName = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string topicList = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional MasterCertificateInfo authInfo = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional ApprovedClientConfig appdConfig = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message HeartResponseM2P {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 errCode = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string errMsg = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int64 brokerCheckSum = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /* brokerId:host:port-topic:partitionNum */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string topicInfos = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string brokerInfos = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional bool requireAuth = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional MasterAuthorizedInfo authorizedInfo = 8;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional ApprovedClientConfig appdConfig = 9;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>topicInfos</strong>: The metadata information corresponding to the Topic published by the SDK, including partition information and the Broker where it is located, is decoded. Since there is a lot of metadata, the outflow generated by passing the object data through as is would be very large, so we made Improvements.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">public static Tuple2&lt;Map&lt;String, Integer&gt;, List&lt;TopicInfo&gt;&gt; convertTopicInfo(</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Map&lt;Integer, BrokerInfo&gt; brokerInfoMap, List&lt;String&gt; strTopicInfos) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> List&lt;TopicInfo&gt; topicList = new ArrayList&lt;&gt;();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Map&lt;String, Integer&gt; topicMaxSizeInBMap = new ConcurrentHashMap&lt;&gt;();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (strTopicInfos == null || strTopicInfos.isEmpty()) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> return new Tuple2&lt;&gt;(topicMaxSizeInBMap, topicList);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> String[] strInfo;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> String[] strTopicInfoSet;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> String[] strTopicInfo;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> BrokerInfo brokerInfo;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> for (String info : strTopicInfos) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (info == null || info.isEmpty()) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> continue;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> info = info.trim();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> strInfo = info.split(TokenConstants.SEGMENT_SEP, -1);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> strTopicInfoSet = strInfo[1].split(TokenConstants.ARRAY_SEP);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> for (String s : strTopicInfoSet) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> strTopicInfo = s.split(TokenConstants.ATTR_SEP);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> brokerInfo = brokerInfoMap.get(Integer.parseInt(strTopicInfo[0]));</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (brokerInfo != null) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> topicList.add(new TopicInfo(brokerInfo,</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> strInfo[0], Integer.parseInt(strTopicInfo[1]),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> Integer.parseInt(strTopicInfo[2]), true, true));</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (strInfo.length == 2 || TStringUtils.isEmpty(strInfo[2])) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> continue;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> try {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> topicMaxSizeInBMap.put(strInfo[0], Integer.parseInt(strInfo[2]));</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> } catch (Throwable e) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> //</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> return new Tuple2&lt;&gt;(topicMaxSizeInBMap, topicList);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>requireAuth</strong>: Code to indicates the expiration of the previous authAuthorizedToken of the Master, requiring the SDK to report the username and password signatures on the next request.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="53-message-producer-exits-from-master">5.3 Message: Producer exits from Master:<a href="#53-message-producer-exits-from-master" class="hash-link" aria-label="Direct link to 5.3 Message: Producer exits from Master:" title="Direct link to 5.3 Message: Producer exits from Master:"></a></h3><hr><div class="language-pro codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-pro codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message CloseRequestP2M{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string clientId = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional MasterCertificateInfo authInfo = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message CloseResponseM2P{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 errCode = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string errMsg = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p>Note that if authentication is enable, closing operation will do the authentication to avoid external interference with the operation.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="54-message-producer-to-broker">5.4 Message: Producer to Broker:<a href="#54-message-producer-to-broker" class="hash-link" aria-label="Direct link to 5.4 Message: Producer to Broker:" title="Direct link to 5.4 Message: Producer to Broker:"></a></h3><hr><p>This part is related to the definition of RPC Message.</p><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message SendMessageRequestP2B {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string clientId = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string topicName = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 partitionId = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required bytes data = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 flag = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 checkSum = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 sentAddr = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional string msgType = 8;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional string msgTime = 9;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional AuthorizedInfo authInfo = 10;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">message SendMessageResponseB2P {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required bool success = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required int32 errCode = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> required string errMsg = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional bool requireAuth = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 messageId = 5;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 appendTime = 6;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 appendOffset = 7;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>Data</strong> is the binary byte stream of Message.</p><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">private byte[] encodePayload(final Message message) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> final byte[] payload = message.getData();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> final String attribute = message.getAttribute();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> if (TStringUtils.isBlank(attribute)) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> return payload;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> byte[] attrData = StringUtils.getBytesUtf8(attribute);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> final ByteBuffer buffer =</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> ByteBuffer.allocate(4 + attrData.length + payload.length);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> buffer.putInt(attrData.length);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> buffer.put(attrData);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> buffer.put(payload);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> return buffer.array();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> }</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>sentAddr</strong> is the local IPv4 address of the machine where the SDK is located converted to a 32-bit numeric ID.</p><p><strong>msgType</strong> is the type of filter message. <code>msgTime</code> is the message time when the SDK sends a message, its value comes from the value filled in by <code>putSystemHeader</code> when constructing Message, and there is a corresponding API in Message to get it.</p><p><strong>requireAuth</strong>: Required authentication operations to Broker for data production, not currently in effect due to performance issues. The authAuthorizedToken value in the sent message is based on the value provided by the Master and will change with the change of the Master.</p><h3 class="anchor anchorWithStickyNavbar_LWe7" id="55-partition-loadbalance">5.5 Partition Loadbalance:<a href="#55-partition-loadbalance" class="hash-link" aria-label="Direct link to 5.5 Partition Loadbalance:" title="Direct link to 5.5 Partition Loadbalance:"></a></h3><hr><p>Apache TubeMQ currently uses a server-side load balancing mode, where the balancing process is managed and maintained by the server; subsequent versions will add a client-side load balancing mode, so that two modes can co-exist.</p><p><strong>Server side load balancing</strong>:</p><ul><li>When the Master process starts, it starts the load-balancing thread balancerChore. balancerChore periodically checks the current registered consumer group for load balancing. The process is simply to evenly distribute the consumer group subscription partitions to registered clients, and periodically detect the current partition of the client If so, the extra partitions will be split to other clients with less number of subscriptions. First, the master checks if the current consumer group needs load balancing. The topic collection is sorted by all partitions of the topic, and all consumer IDs of this consumer group, and then by the consumer group&#x27;s all Divide and model the number of partitions and the number of clients to get the number of partitions each client subscribes to at most; then give each client the Assign partitions and carry the partition information in the heartbeat response when the consumer subscribes; if the client has more than one partition currently in place Give the client a partition release command to partition the partition away from the consumer, and to the assigned consumer A partition assignment instruction that informs that the partition is assigned to the corresponding client is as follows.</li></ul><p>Translated with <a href="http://www.DeepL.com/Translator" target="_blank" rel="noopener noreferrer">www.DeepL.com/Translator</a> (free version)</p><div class="language-protobuf codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-protobuf codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">message EventProto{</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int64 rebalanceId = 1;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int32 opType = 2;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> optional int32 status = 3;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /* consumerId@group-brokerId:host:port-topic:partitionId */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> repeated string subscribeInfo = 4;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>rebalanceId</strong>:A long-type auto-increment number that indicates the round of load balance.</p><p><strong>opType</strong>:Operation code, and its value defined in EventType. There are only four parts of the opcode that have been implemented, as follows: <code>DISCONNECT</code>, <code>CONNECT</code>, <code>REPORT</code> and <code>ONLY_</code>. Opcode started with <code>ONLY</code> is not detailed developed.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">switch (event.getType()) {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case DISCONNECT:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case ONLY_DISCONNECT:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> disconnectFromBroker(event);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> rebalanceResults.put(event);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> break;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case CONNECT:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case ONLY_CONNECT:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> connect2Broker(event);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> rebalanceResults.put(event);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> break;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case REPORT:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> reportSubscribeInfo();</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> break;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> case STOPREBALANCE:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> break;</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> default:</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> throw new TubeClientException(strBuffer</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .append(&quot;Invalid rebalance opCode:&quot;)</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> .append(event.getType()).toString());</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>status</strong>:Defined in <code>EventStatus</code>, indicates the status of the event. When Master constructs a load balancing task, it sets the status to <code>TODO</code>. When receiving the client heartbeat request, master writes the task to the response message and sets the status to <code>PROCESSING</code>. The client receives a load balancing command from the heartbeat response, and then it can perform the actual connection or disconnection operation, after the operation is finished, set the command status to <code>DONE</code> until sending next heartbeat to master.</p><div class="language-java codeBlockContainer_Ckt0 theme-code-block" style="--prism-color:#F8F8F2;--prism-background-color:#282A36"><div class="codeBlockContent_biex"><pre tabindex="0" class="prism-code language-java codeBlock_bY9V thin-scrollbar"><code class="codeBlockLines_e6Vv"><span class="token-line" style="color:#F8F8F2"><span class="token plain">public enum EventStatus {</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * To be processed state.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> TODO(0, &quot;To be processed&quot;),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * On processing state.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> PROCESSING(1, &quot;Being processed&quot;),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * Processed state.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> DONE(2, &quot;Process Done&quot;),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain" style="display:inline-block"></span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * Unknown state.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> UNKNOWN(-1, &quot;Unknown event status&quot;),</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> /**</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * Failed state.</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> * */</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain"> FAILED(-2, &quot;Process failed&quot;);</span><br></span><span class="token-line" style="color:#F8F8F2"><span class="token plain">}</span><br></span></code></pre><div class="buttonGroup__atx"><button type="button" aria-label="Copy code to clipboard" title="Copy" class="clean-btn"><span class="copyButtonIcons_eSgA" aria-hidden="true"><svg class="copyButtonIcon_y97N" viewBox="0 0 24 24"><path d="M19,21H8V7H19M19,5H8A2,2 0 0,0 6,7V21A2,2 0 0,0 8,23H19A2,2 0 0,0 21,21V7A2,2 0 0,0 19,5M16,1H4A2,2 0 0,0 2,3V17H4V3H16V1Z"></path></svg><svg class="copyButtonSuccessIcon_LjdS" viewBox="0 0 24 24"><path d="M21,7L9,19L3.5,13.5L4.91,12.09L9,16.17L19.59,5.59L21,7Z"></path></svg></span></button></div></div></div><p><strong>subscribeInfo</strong> indicates assigned partition information, in the format suggested by the comment.</p><ul><li>Consumer Operation: When consumer receives metadata returned from master, it should establish the connection and release the operation(Refer to the opType note above). When connection established, return the operation result to master so that consumer can receive some relative job and perform. What we need to know is the LoadBalance of registration is a best-effort operation, if a new consumer send a request for connection before the consumer who occupanies the partition quits, it will receive <code>PARTITION\_OCCUPIED</code> exception response. And at this time partition tries to remove it from its queue. And partition consumer will also remove it when receiving corresponding response so that the consumer could successfully register to this partition in next load balance.</li></ul></div><footer class="theme-doc-footer docusaurus-mt-lg"><div class="theme-doc-footer-edit-meta-row row"><div class="col"><a href="https://github.com/apache/inlong-website/edit/master/versioned_docs/version-1.8.0/modules/tubemq/client_rpc.md" target="_blank" rel="noreferrer noopener" class="theme-edit-this-page"><svg fill="currentColor" height="20" width="20" viewBox="0 0 40 40" class="iconEdit_Z9Sw" aria-hidden="true"><g><path d="m34.5 11.7l-3 3.1-6.3-6.3 3.1-3q0.5-0.5 1.2-0.5t1.1 0.5l3.9 3.9q0.5 0.4 0.5 1.1t-0.5 1.2z m-29.5 17.1l18.4-18.5 6.3 6.3-18.4 18.4h-6.3v-6.2z"></path></g></svg>Edit this page</a></div><div class="col lastUpdated_vwxv"></div></div></footer></article><nav class="pagination-nav docusaurus-mt-lg" aria-label="Docs pages navigation"><a class="pagination-nav__link pagination-nav__link--prev" href="/docs/1.8.0/modules/tubemq/client_partition_assign_introduction"><div class="pagination-nav__sublabel">Previous</div><div class="pagination-nav__label">client partition assign</div></a><a class="pagination-nav__link pagination-nav__link--next" href="/docs/1.8.0/modules/tubemq/clients_java"><div class="pagination-nav__sublabel">Next</div><div class="pagination-nav__label">TubeMQ JAVA SDK API</div></a></nav></div></div><div class="col col--3"><div class="tableOfContents_bqdL thin-scrollbar theme-doc-toc-desktop"><ul class="table-of-contents table-of-contents__left-border"><li><a href="#1-general-introduction" class="table-of-contents__link toc-highlight">1 General Introduction</a></li><li><a href="#2-pb-format-code" class="table-of-contents__link toc-highlight">2 PB format code:</a></li><li><a href="#3-interactive-diagram-of-the-clients-pb-request--response" class="table-of-contents__link toc-highlight">3 Interactive diagram of the client&#39;s PB request &amp; response:</a></li><li><a href="#4-client-feature" class="table-of-contents__link toc-highlight">4 Client feature:</a></li><li><a href="#5-client-function-induction-casebycase" class="table-of-contents__link toc-highlight">5 Client function Induction CaseByCase:</a><ul><li><a href="#51-message-producer-register-to-master" class="table-of-contents__link toc-highlight">5.1 Message: Producer register to Master:</a></li><li><a href="#52-mseeage-heartbeat-from-producer-to-master" class="table-of-contents__link toc-highlight">5.2 Mseeage: Heartbeat from Producer to Master:</a></li><li><a href="#53-message-producer-exits-from-master" class="table-of-contents__link toc-highlight">5.3 Message: Producer exits from Master:</a></li><li><a href="#54-message-producer-to-broker" class="table-of-contents__link toc-highlight">5.4 Message: Producer to Broker:</a></li><li><a href="#55-partition-loadbalance" class="table-of-contents__link toc-highlight">5.5 Partition Loadbalance:</a></li></ul></li></ul></div></div></div></div></main></div></div><footer class="footer"><div class="container container-fluid"><div class="row footer__links"><div class="col footer__col"><div class="footer__title">Events</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://www.apachecon.com/" target="_blank" rel="noopener noreferrer" class="footer__link-item">ApacheCon<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a class="acevent" data-format="square" data-mode="dark" data-event="random"></a></li></ul></div><div class="col footer__col"><div class="footer__title">Community</div><ul class="footer__items clean-list"><li class="footer__item"><a href="https://twitter.com/ApacheInlong" target="_blank" rel="noopener noreferrer" class="footer__link-item">Twitter<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="https://inlong.apache.org/img/apache-inlong-wechat.jpg" target="_blank" rel="noopener noreferrer" class="footer__link-item">WeChat<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li><li class="footer__item"><a href="mailto:dev@inlong.apache.org" target="_blank" rel="noopener noreferrer" class="footer__link-item">Email</a></li></ul></div><div class="col footer__col"><div class="footer__title">More</div><ul class="footer__items clean-list"><li class="footer__item"><a class="footer__link-item" href="/blog">Blog</a></li><li class="footer__item"><a href="https://github.com/apache/inlong" target="_blank" rel="noopener noreferrer" class="footer__link-item">GitHub<svg width="13.5" height="13.5" aria-hidden="true" viewBox="0 0 24 24" class="iconExternalLink_nPIU"><path fill="currentColor" d="M21 13v10h-21v-19h12v2h-10v15h17v-8h2zm3-12h-10.988l4.035 4-6.977 7.07 2.828 2.828 6.977-7.07 4.125 4.172v-11z"></path></svg></a></li></ul></div></div><div class="footer__bottom text--center"><div class="margin-bottom--sm"><img src="/img/asf_logo.svg" alt="Apache InLong" class="themedImage_ToTc themedImage--light_HNdA footer__logo"><img src="/img/asf_logo.svg" alt="Apache InLong" class="themedImage_ToTc themedImage--dark_i4oU footer__logo"></div><div class="footer__copyright"><div style="font-family: Avenir-Medium;font-size: 14px;color: #999;">
<div>Copyright © 2020-2024 The Apache Software Foundation. Licensed under the Apache License, Version 2.0.</div>
<div style="margin-top: 20px; padding-top: 20px; border-top: 1px solid #666;line-height: 20px;">The Apache Software Foundation Apache InLong, InLong, Apache, the Apache feather, and the Apache InLong project logo are either registered trademarks or trademarks of the Apache Software Foundation.</div>
</div></div></div></div></footer></div>
<script src="/assets/js/runtime~main.63c98e82.js"></script>
<script src="/assets/js/main.070aef2a.js"></script>
</body>
</html>