blob: 6b45262984557e4f9e2aacb80cfd9534e4119080 [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<title>Examples - Dubbo - Alibaba Open Sesame</title>
<meta http-equiv="X-UA-Compatible" content="IE=8">
<meta charset="UTF-8">
<!-- Deprecated since 3.4. To be removed in a future version of Confluence; use AJS.Confluence.getContextPath() -->
<meta id="confluence-context-path" name="confluence-context-path" content="/wiki">
<meta name="ajs-context-path" content="/wiki">
<meta name="ajs-version-number" content="3.5.9">
<meta name="ajs-build-number" content="2166">
<meta id="atlassian-token" name="atlassian-token" content="c116db80711201b36e2067aa83f3b044c2d5a30e">
<meta id="confluence-space-key" name="confluence-space-key" content="dubbo">
<meta name="ajs-remote-user" content="">
<meta name="ajs-static-resource-url-prefix" content="/wiki/s/en/2166/34/_">
<script type="text/javascript">
// Deprecated global variables. To be removed in a future version of Confluence.
var contextPath = '/wiki';
</script>
<!-- include system css resources -->
<link type="text/css" rel="stylesheet" href="batch.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/26/_/download/superbatch/css/batch.css" media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="batch.css-ieonly=true.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/26/_/download/superbatch/css/batch.css?ieonly=true" media="all">
<![endif]-->
<link type="text/css" rel="stylesheet" href="batch.css-media=print.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/26/_/download/superbatch/css/batch.css?media=print" media="print">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.ext.newcode-macro-plugin-syntaxhighlighter.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.9.10/_/download/batch/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.ext.newcode-macro-plugin-sh-theme-confluence.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.9.10/_/download/batch/com.atlassian.confluence.ext.newcode-macro-plugin:sh-theme-confluence/com.atlassian.confluence.ext.newcode-macro-plugin:sh-theme-confluence.css" media="all">
<link type="text/css" rel="stylesheet" href="confluence-forms.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/resources/confluence.web.resources:aui-forms/confluence-forms.css" media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="confluence.web.resources-aui-forms.css-ieonly=true.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:aui-forms/confluence.web.resources:aui-forms.css?ieonly=true" media="all">
<![endif]-->
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.plugins.share-page-mail-page-resources.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.8/_/download/batch/com.atlassian.confluence.plugins.share-page:mail-page-resources/com.atlassian.confluence.plugins.share-page:mail-page-resources.css" media="all">
<link type="text/css" rel="stylesheet" href="confluence.web.resources-view-comment.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:view-comment/confluence.web.resources:view-comment.css" media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="confluence.web.resources-view-comment.css-ieonly=true.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:view-comment/confluence.web.resources:view-comment.css?ieonly=true" media="all">
<![endif]-->
<link type="text/css" rel="stylesheet" href="confluence.macros.advanced-fancy-box.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.16/_/download/batch/confluence.macros.advanced:fancy-box/confluence.macros.advanced:fancy-box.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.plugins.drag-and-drop-support.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0.16/_/download/batch/com.atlassian.confluence.plugins.drag-and-drop:support/com.atlassian.confluence.plugins.drag-and-drop:support.css" media="all">
<link type="text/css" rel="stylesheet" href="confluence.extra.jira-macro-browser-resources.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.1.2/_/download/batch/confluence.extra.jira:macro-browser-resources/confluence.extra.jira:macro-browser-resources.css" media="all">
<link type="text/css" rel="stylesheet" href="confluence.web.resources-page-editor.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:page-editor/confluence.web.resources:page-editor.css" media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="confluence.web.resources-page-editor.css-ieonly=true.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:page-editor/confluence.web.resources:page-editor.css?ieonly=true" media="all">
<![endif]-->
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.tinymceplugin-editor-resources.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-resources/com.atlassian.confluence.tinymceplugin:editor-resources.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.plugins.linkbrowser-linkbrowser-resources.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources.css" media="all">
<!--[if IE]>
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.plugins.linkbrowser-linkbrowser-resources.css-ieonly=true.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources.css?ieonly=true" media="all">
<![endif]-->
<link type="text/css" rel="stylesheet" href="confluence-draft-changes-draft-changes.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence-draft-changes:draft-changes/confluence-draft-changes:draft-changes.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.plugins.jira.jira-connector-dialogsJs.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/com.atlassian.confluence.plugins.jira.jira-connector:dialogsJs/com.atlassian.confluence.plugins.jira.jira-connector:dialogsJs.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.plugins.shortcuts.atlassian-shortcuts-module-shortcuts.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/0.8/_/download/batch/com.atlassian.plugins.shortcuts.atlassian-shortcuts-module:shortcuts/com.atlassian.plugins.shortcuts.atlassian-shortcuts-module:shortcuts.css" media="all">
<link type="text/css" rel="stylesheet" href="com.atlassian.confluence.keyboardshortcuts-confluence-keyboard-shortcuts.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.keyboardshortcuts:confluence-keyboard-shortcuts/com.atlassian.confluence.keyboardshortcuts:confluence-keyboard-shortcuts.css" media="all">
<!-- end system css resources -->
<link rel="stylesheet" href="combined.css-spaceKey=dubbo.css" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3/_/styles/combined.css?spaceKey=dubbo" type="text/css">
<meta name="confluence-request-time" content="1392025757803">
<meta name="loggedInUsername" content="">
<meta name="ajs-keyboardshortcut-hash" content="bf02a79603372a43d395a0a429bdf66">
<!-- Deprecated since 3.4. To be removed in a future version of Confluence; use atl.header -->
<script type="text/x-template" title="share-content-popup">
<form action="#" method="post" class="aui share-content-popup">
<fieldset>
<label for="users">User name or email</label>
<div class="autocomplete-user-target">
<input class="text autocomplete-sharepage" id="users" data-max="10" data-dropdown-target=".autocomplete-user-target" data-none-message="No matching user or email found"/>
</div>
<ol class="recipients">
</ol>
<div><label for="note">Note</label></div>
<textarea class="textarea" id="note" placeholder="Add an optional note"/>
</fieldset>
<div class="button-panel">
<div class="progress-messages-icon"></div>
<div class="progress-messages">
</div>
<input class="button submit" type="submit" value="Share" disabled/>
<a class="close-dialog" href="#">Cancel</a>
</div>
</form>
</script>
<script type="text/x-template" title="share-content-popup-recipient-username">
<li data-username="{username}" style="display: none">
<span>
<img src="{thumbnailLink.href}" title="{title}">
<span>{title}</span>
<span class="remove-recipient"/>
</span>
</li>
</script>
<script type="text/x-template" title="share-content-popup-recipient-email">
<li data-email="{email}" style="display: none">
<span>
<img src="{icon}" title="{email}">
<span>{email}</span>
<span class="remove-recipient"/>
</span>
</li>
</script>
<meta name="ajs-use-keyboard-shortcuts" content="true">
<link rel="shortcut icon" href="/wiki/favicon.ico">
<link rel="icon" type="image/png" href="/wiki/s/en/2166/34/_/images/logo/confluence_16.png">
<link rel="search" type="application/opensearchdescription+xml" href="/wiki/opensearch/osd.action" title="Alibaba Open Sesame"/>
<!-- include system javascript resources -->
<script type="text/javascript" src="batch.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/26/_/download/superbatch/js/batch.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.ext.newcode-macro-plugin-syntaxhighlighter.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.9.10/_/download/batch/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.ext.newcode-macro-plugin-syntaxhighlighter-brushes.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.9.10/_/download/batch/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter-brushes/com.atlassian.confluence.ext.newcode-macro-plugin:syntaxhighlighter-brushes.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.share-page-mail-page-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.8/_/download/batch/com.atlassian.confluence.plugins.share-page:mail-page-resources/com.atlassian.confluence.plugins.share-page:mail-page-resources.js" ></script>
<script type="text/javascript" src="confluence.macros.advanced-fancy-box.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.16/_/download/batch/confluence.macros.advanced:fancy-box/confluence.macros.advanced:fancy-box.js" ></script>
<script type="text/javascript" src="confluence.macros.advanced-thumbnail-images.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.16/_/download/batch/confluence.macros.advanced:thumbnail-images/confluence.macros.advanced:thumbnail-images.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.drag-and-drop-support.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0.16/_/download/batch/com.atlassian.confluence.plugins.drag-and-drop:support/com.atlassian.confluence.plugins.drag-and-drop:support.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.drag-and-drop-drag-and-drop-for-view-content.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0.16/_/download/batch/com.atlassian.confluence.plugins.drag-and-drop:drag-and-drop-for-view-content/com.atlassian.confluence.plugins.drag-and-drop:drag-and-drop-for-view-content.js" ></script>
<script type="text/javascript" src="confluence.web.resources-page-editor.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:page-editor/confluence.web.resources:page-editor.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.tinymceplugin-editor-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-resources/com.atlassian.confluence.tinymceplugin:editor-resources.js" ></script>
<script type="text/javascript" src="linkbrowser.nocache.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/resources/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources/war/linkbrowser/linkbrowser.nocache.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.linkbrowser-linkbrowser-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources/com.atlassian.confluence.plugins.linkbrowser:linkbrowser-resources.js" ></script>
<script type="text/javascript" src="confluence-draft-changes-draft-changes.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence-draft-changes:draft-changes/confluence-draft-changes:draft-changes.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.tinymceplugin-editor-autocomplete-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-autocomplete-resources/com.atlassian.confluence.tinymceplugin:editor-autocomplete-resources.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.tinymceplugin-editor-autocomplete-links.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-autocomplete-links/com.atlassian.confluence.tinymceplugin:editor-autocomplete-links.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.tinymceplugin-editor-autocomplete-media.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-autocomplete-media/com.atlassian.confluence.tinymceplugin:editor-autocomplete-media.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.tinymceplugin-editor-autocomplete-macros.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.tinymceplugin:editor-autocomplete-macros/com.atlassian.confluence.tinymceplugin:editor-autocomplete-macros.js" ></script>
<script type="text/javascript" src="com.atlassian.applinks.applinks-plugin-applinks-util-js.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.3/_/download/batch/com.atlassian.applinks.applinks-plugin:applinks-util-js/com.atlassian.applinks.applinks-plugin:applinks-util-js.js" ></script>
<script type="text/javascript" src="com.atlassian.applinks.applinks-plugin-applinks-oauth-ui.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.3/_/download/batch/com.atlassian.applinks.applinks-plugin:applinks-oauth-ui/com.atlassian.applinks.applinks-plugin:applinks-oauth-ui.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.jira.jira-connector-proxy-js.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/com.atlassian.confluence.plugins.jira.jira-connector:proxy-js/com.atlassian.confluence.plugins.jira.jira-connector:proxy-js.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.jira.jira-connector-dialogsJs.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/com.atlassian.confluence.plugins.jira.jira-connector:dialogsJs/com.atlassian.confluence.plugins.jira.jira-connector:dialogsJs.js" ></script>
<script type="text/javascript" src="confluence.web.resources-help-content-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/confluence.web.resources:help-content-resources/confluence.web.resources:help-content-resources.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.drag-and-drop-drag-and-drop-for-editor.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0.16/_/download/batch/com.atlassian.confluence.plugins.drag-and-drop:drag-and-drop-for-editor/com.atlassian.confluence.plugins.drag-and-drop:drag-and-drop-for-editor.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.drag-and-drop-drop-zone-for-image-dialog.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0.16/_/download/batch/com.atlassian.confluence.plugins.drag-and-drop:drop-zone-for-image-dialog/com.atlassian.confluence.plugins.drag-and-drop:drop-zone-for-image-dialog.js" ></script>
<script type="text/javascript" src="com.atlassian.gadgets.embedded-gadget-core-resources.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/2.0.8/_/download/batch/com.atlassian.gadgets.embedded:gadget-core-resources/com.atlassian.gadgets.embedded:gadget-core-resources.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.gadgets-macro-browser-for-gadgetsplugin.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.1.5/_/download/batch/com.atlassian.confluence.plugins.gadgets:macro-browser-for-gadgetsplugin/com.atlassian.confluence.plugins.gadgets:macro-browser-for-gadgetsplugin.js" ></script>
<script type="text/javascript" src="confluence.macros.core-macro-browser-smart-fields.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/confluence.macros.core:macro-browser-smart-fields/confluence.macros.core:macro-browser-smart-fields.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.plugins.doctheme-splitter.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.9/_/download/batch/com.atlassian.confluence.plugins.doctheme:splitter/com.atlassian.confluence.plugins.doctheme:splitter.js" ></script>
<script type="text/javascript" src="com.atlassian.plugins.shortcuts.atlassian-shortcuts-module-shortcuts.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/0.8/_/download/batch/com.atlassian.plugins.shortcuts.atlassian-shortcuts-module:shortcuts/com.atlassian.plugins.shortcuts.atlassian-shortcuts-module:shortcuts.js" ></script>
<script type="text/javascript" src="com.atlassian.confluence.keyboardshortcuts-confluence-keyboard-shortcuts.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/3.5.9/_/download/batch/com.atlassian.confluence.keyboardshortcuts:confluence-keyboard-shortcuts/com.atlassian.confluence.keyboardshortcuts:confluence-keyboard-shortcuts.js" ></script>
<script type="text/javascript" src="legacy.confluence.web.resources-prototype.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/1.0/_/download/batch/legacy.confluence.web.resources:prototype/legacy.confluence.web.resources:prototype.js" ></script>
<!-- end system javascript resources -->
<link rel="canonical" href="http://code.alibabatech.com/wiki/display/dubbo/Examples">
<link rel="shortlink" href="http://code.alibabatech.com/wiki/x/JQFq">
<meta name="wikilink" content="[dubbo:Examples]">
<meta name="page-version" content="146">
</head>
<body onload="placeFocus()"
id="com-atlassian-confluence" class="theme-default ">
<ul id="assistive-skip-links" class="assistive">
<li><a href="#title-heading">Skip to content</a></li>
<li><a href="#breadcrumbs">Skip to breadcrumbs</a></li>
<li><a href="#header-menu-bar">Skip to header menu</a></li>
<li><a href="#navigation">Skip to action menu</a></li>
<li><a href="#quick-search-query">Skip to quick search</a></li>
</ul>
<div id="page">
<div id="full-height-container">
<fieldset class="hidden parameters">
<input type="hidden" id="shortcutDialogTip" value="Shortcut tip: Pressing <b>{shortcut}</b> also opens this dialog box">
<input type="hidden" title="i18n.close.name" value="Close">
<input type="hidden" title="i18n.cancel.name" value="Cancel">
</fieldset><fieldset class="hidden parameters">
<input type="hidden" id="statusDialogHeading" value="What are you working on?">
<input type="hidden" id="statusDialogAccessibilityLabel" value="Enter your status (140 character limit)">
<input type="hidden" id="statusDialogLatestLabel" value="Last update:">
<input type="hidden" id="statusDialogUpdateButtonLabel" value="Update">
<input type="hidden" id="statusDialogCancelButtonLabel" value="Cancel">
</fieldset>
<fieldset class="hidden parameters">
<input type="hidden" id="globalSettingsAttachmentMaxSize" value="10485760">
<input type="hidden" id="userLocale" value="en_GB">
<input type="hidden" id="staticResourceUrlPrefix" value="/wiki/s/en/2166/34/_">
<input type="hidden" id="contextPath" value="/wiki">
</fieldset>
<div id="header" class="" style="display: none">
<form id="quick-search" class="quick-search" method="get" action="http://10.20.160.198/wiki/dosearchsite.action">
<fieldset>
<label class="assistive" for="quick-search-query">Quick Search</label>
<input class="quick-search-query" id="quick-search-query" type="text" accessKey="q" autocomplete="off" name="queryString" size="25" title="Quick Search" />
<input class="quick-search-submit" id="quick-search-submit" type="submit" value="Search" />
<div class="aui-dd-parent quick-nav-drop-down"><!-- Quick nav appears here --></div>
</fieldset>
<fieldset class="hidden parameters">
<input type="hidden" id="quickNavEnabled" value="true" />
</fieldset>
</form>
<ul id="header-menu-bar" class="ajs-menu-bar">
<li class="normal ajs-menu-item">
<a id="browse-menu-link" class="browse trigger ajs-menu-title" href="#"><span><span>Browse</span></span></a> <div class="assistive ajs-drop-down">
<ul id="browse-menu-link-leading" class="section-leading first">
<li>
<a id="space-pages-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/listpages.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/listpages.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/pages/listpages.action?key=dubbo" class="" title="Browse pages in the Dubbo space">
<span>Pages</span></a> </li>
<li>
<a id="space-blogposts-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewrecentblogposts.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewrecentblogposts.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/pages/viewrecentblogposts.action?key=dubbo" class="" title="Browse blogs in the Dubbo space">
<span>Blog</span></a> </li>
<li>
<a id="space-labels-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/labels/listlabels-heatmap.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/labels/listlabels-heatmap.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/labels/listlabels-heatmap.action?key=dubbo" class="" title="Browse labels in the Dubbo space">
<span>Labels</span></a> </li>
<li>
<a id="space-attachments-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/spaces/listattachmentsforspace.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/spaces/listattachmentsforspace.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/spaces/listattachmentsforspace.action?key=dubbo" class="" title="Browse attachments in the Dubbo space">
<span>Attachments</span></a> </li>
<li>
<a id="space-mail-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/spaces/viewmailarchive.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/spaces/viewmailarchive.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/spaces/viewmailarchive.action?key=dubbo" class="" title="Browse mail in the Dubbo space">
<span>Mail</span></a> </li>
<li>
<a id="space-advanced-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/spaces/viewspacesummary.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/spaces/viewspacesummary.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/spaces/viewspacesummary.action?key=dubbo" class="" title="Browse additional space functions in the Dubbo space">
<span>Advanced</span></a> </li>
<li>
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/spaces/usage/report.action?key=dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/spaces/usage/report.action?key=dubbo%27" tppabs="http://10.20.160.198/wiki/spaces/usage/report.action?key=dubbo" class="" title="">
<span>Activity</span></a> </li>
</ul>
<ul id="browse-menu-link-global" class="section-global">
<li>
<a id="whats-new-menu-link" href="javascript:if(confirm(%27http://docs.atlassian.com/confluence/docs-35/whatsnew/iframe \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://docs.atlassian.com/confluence/docs-35/whatsnew/iframe%27" tppabs="http://docs.atlassian.com/confluence/docs-35/whatsnew/iframe" class="" title="">
<span>What’s New</span></a> </li>
<li>
<a id="people-directory-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/peopledirectory.action \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/peopledirectory.action%27" tppabs="http://10.20.160.198/wiki/peopledirectory.action" class="" title="Browse the Confluence people directory">
<span>People Directory</span></a> </li>
<li>
<a id="space-directory-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/spacedirectory/view.action \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/spacedirectory/view.action%27" tppabs="http://10.20.160.198/wiki/spacedirectory/view.action" class="" title="Browse the Confluence space directory">
<span>Space Directory</span></a> </li>
<li>
<a id="keyboard-shortcuts-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki%27" tppabs="http://10.20.160.198/wiki" class="" title="View available keyboard shortcuts">
<span>Keyboard Shortcuts</span></a> </li>
<li>
<a id="gadget-directory-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki%27" tppabs="http://10.20.160.198/wiki" class="user-item administration-link" title="Browse gadgets provided by Confluence">
<span>Confluence Gadgets</span></a> </li>
</ul>
</div>
</li>
<li class="ajs-menu-item normal">
<a id="login-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/login.action?os_destination=%2Fdisplay%2Fdubbo%2FExamples%3FshowComments%3Dtrue%26showCommentArea%3Dtrue \n\nThis file was not retrieved by Teleport Ultra, because it is linked too far away from its Starting Address. If you increase the in-domain depth setting for the Starting Address, this file will be queued for retrieval. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/login.action?os_destination=%2Fdisplay%2Fdubbo%2FExamples%3FshowComments%3Dtrue%26showCommentArea%3Dtrue%27" tppabs="http://10.20.160.198/wiki/login.action?os_destination=%2Fdisplay%2Fdubbo%2FExamples%3FshowComments%3Dtrue%26showCommentArea%3Dtrue" class="user-item login-link" title="">
<span>Log In</span></a> </li>
</ul>
<ol id="breadcrumbs">
<li class="first" >
<span><a href="javascript:if(confirm(%27http://10.20.160.198/wiki/dashboard.action \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/dashboard.action%27" tppabs="http://10.20.160.198/wiki/dashboard.action" title="Go to Dashboard">Dashboard</a></span>
</li>
<li>
<span><a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo%27" tppabs="http://10.20.160.198/wiki/display/dubbo">Dubbo</a></span>
</li>
<li id="ellipsis" title="Show all breadcrumbs"><span><strong>&#8230;</strong></span></li>
<li class="hidden-crumb" >
<span><a href="Home.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Home">Home</a></span>
</li>
<li>
<span><a href="User+Guide.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/User+Guide">User Guide</a></span>
</li>
<li>
<span>Examples</span>
</li>
</ol>
</div><!-- \#header -->
<div id="main" >
<div id="navigation" class="content-navigation view" style="display: none">
<fieldset class="hidden parameters">
<input type="hidden" id="pageId" value="6947109">
</fieldset>
<ul class="ajs-menu-bar">
<li class="normal ajs-menu-item">
<a id="add-menu-link" class="add trigger ajs-menu-title" href="#"><span><span>Add</span></span></a> <div class="assistive ajs-drop-down">
<ul id="add-menu-link-page" class="section-page first">
<li>
<a id="add-comment-menu-link" href="Examples-showComments=true&showCommentArea=true.htm#addcomment" tppabs="http://10.20.160.198/wiki/display/dubbo/Examples?showComments=true&showCommentArea=true#addcomment" class="add-comment" title="Add a Comment">
<span>Comment</span></a> </li>
</ul>
</div>
</li>
<li class="normal ajs-menu-item">
<a id="action-menu-link" class="action trigger ajs-menu-title" href="#"><span><span>Tools</span></span></a> <div class="assistive ajs-drop-down">
<ul id="action-menu-link-primary" class="section-primary first">
<li>
<a id="view-attachments-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewpageattachments.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewpageattachments.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewpageattachments.action?pageId=6947109" class="action-view-attachments" accessKey="a" title="View Attachments">
<span><u>A</u>ttachments (0)</span></a> </li>
<li>
<a id="action-view-history-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewpreviousversions.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewpreviousversions.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewpreviousversions.action?pageId=6947109" class="action-view-history" title="">
<span>Page History</span></a> </li>
<li>
<a id="action-page-permissions-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109" class="action-page-permissions" title="Edit restrictions">
<span>Restrictions</span></a> </li>
</ul>
<ul id="action-menu-link-secondary" class="section-secondary">
<li>
<a id="view-page-info-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109" class="action-view-info" title="">
<span>Info</span></a> </li>
<li>
<a id="link-to-page-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewinfo.action?pageId=6947109" class="" title="Link to this Page">
<span>Link to this Page&hellip;</span></a> </li>
<li>
<a id="view-in-hierarchy-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109#selectedPageInHierarchy%27" tppabs="http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109#selectedPageInHierarchy" class="" title="">
<span>View in Hierarchy</span></a> </li>
<li>
<a id="action-view-source-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/viewpagesrc.action?pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/viewpagesrc.action?pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/viewpagesrc.action?pageId=6947109" class="action-view-source popup-link" title="">
<span>View Wiki Markup</span></a> </li>
</ul>
</div>
</li>
</ul>
</div>
<h1 id="title-heading" class="pagetitle" style="display: none">
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo%27" tppabs="http://10.20.160.198/wiki/display/dubbo"><img class="logo space custom" src="dubbo-version=5&modificationDate=1320723683000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6324241/dubbo?version=5&modificationDate=1320723683000" alt=""></a>
</h1>
<div id="content" class="page view">
<div id="link-to-page-fields" class="hidden parameters">
<input type="hidden" id="linkToThisPageHeading" value="Link to this Page">
<input type="hidden" id="linkToThisPageLink" value="Link">
<input type="hidden" id="linkToThisPageTinyLink" value="Tiny Link">
<input type="hidden" id="linkToThisPageWikiMarkup" value="Wiki Markup">
<input type="hidden" id="linkToThisPageClose" value="Close">
</div>
<fieldset class="hidden parameters">
<input type="hidden" title="movePageDialogViewPageTitle" value="Move Page &ndash; &#8216;Examples&#8217;">
<input type="hidden" title="movePageDialogEditPageTitle" value="Set Page Location">
<input type="hidden" title="movePageDialogMoveButton" value="Move">
<input type="hidden" title="movePageDialogCancelButton" value="Cancel">
<input type="hidden" title="movePageDialogBrowsePanelTip" value="Click to select the new parent page for this page and its children.">
<input type="hidden" title="movePageDialogSearchPanel" value="Search">
<input type="hidden" title="movePageDialogHistoryPanel" value="Recently Viewed">
<input type="hidden" title="movePageDialogHistoryNoResults" value="There were no recently viewed pages found.">
<input type="hidden" title="movePageDialogLocationPanel" value="Known Location">
<input type="hidden" title="movePageDialogLocationNotFound" value="The specified page was not found.">
<input type="hidden" title="movePageDialogBrowsePanel" value="Browse">
<input type="hidden" title="movePageDialogPanelLoadErrorMsg" value="Error reading the panel content from the server.">
<input type="hidden" title="movePageDialogPanelLoadErrorTip" value="You could try reloading the page and launching the dialog again.">
<input type="hidden" title="movePageDialogPanelLoadErrorStatus" value="HTTP Status">
<input type="hidden" title="movePageDialogNoSelectionErrorMsg" value="You must make a selection in the tree before you can move the page.">
<input type="hidden" title="movePageDialogSearchError" value="Failed to retrieve search results from the server.">
<input type="hidden" title="movePageDialogSearchNoResults" value="There were no pages found containing <b>{0}</b>.">
<input type="hidden" title="movePageDialogSearchResultCount" value="Showing <b>{0}</b>-<b>{1}</b> of <b>{2}</b> pages containing <b>{3}</b>.">
<input type="hidden" title="movePageDialogMoveFailed" value="Move failed. There was a problem contacting the server.">
<input type="hidden" title="movePageDialogCannotChangeSpace" value="You cannot move this page to another space because you do not have permission to remove it from this space.">
<input type="hidden" title="pageTitle" value="Examples"/>
<input type="hidden" title="parentPageTitle" value="User Guide"/>
<input type="hidden" title="fromPageTitle" value=""/>
<input type="hidden" title="spaceKey" value="dubbo"/>
<input type="hidden" title="spaceName" value="Dubbo"/>
<input type="hidden" title="movePageDialogInvalidLocation" value="You cannot move a page to be underneath itself or its children."/>
<input type="hidden" title="movePageDialogOrderingTitle" value="Page Ordering"/>
<input type="hidden" title="movePageDialogBackButton" value="Back"/>
<input type="hidden" title="movePageDialogMoveAndOrderButton" value="Reorder"/>
<input type="hidden" title="movePageDialogNextButton" value="Move"/>
</fieldset>
<script type="text/x-template" title="movePageDialog">
<div class="row information">
<div class="inner">
<div class="element">
Specify the new parent page for this page and its children by space and title.
</div>
</div>
</div>
<div class="form">
<fieldset>
<legend class="assistive"><span>Change the Parent Page to a Known Page</span></legend>
<div class="row">
<label for="new-space">New space:</label>
<div class="value new-space-value">
<input id="new-space-key" name="new-space-key" type="hidden" value="dubbo">
<span class="space-input">
<input id="new-space" name="new-space" value="Dubbo" disabled="disabled">
</span>
<span class="description warning">You cannot move this page to another space because you do not have permission to remove it from this space.</span>
<div class="new-space-dropdown aui-dd-parent autocomplete"></div>
</div>
</div>
<div class="row">
<label for="new-parent-page">New parent page:</label>
<div class="value new-parent-page-value">
<span class="page-input">
<input id="new-parent-page" name="new-parent-page" value="User Guide">
</span>
<span class="description">Start typing a page title to see a list of suggestions.</span>
<div class="new-parent-page-dropdown aui-dd-parent autocomplete"></div>
</div>
</div>
</fieldset>
</div>
<div class="location-info">
<div class="row">
<label>Current location:</label>
<div class="value breadcrumbs-container">
<div class="breadcrumbs-line">
<ul id="current-parent-breadcrumbs" class="breadcrumbs">
</ul>
</div>
</div>
</div>
<div class="row">
<label>New location:</label>
<div class="value breadcrumbs-container">
<div class="breadcrumbs-line">
<ul id="new-parent-breadcrumbs" class="breadcrumbs">
</ul>
</div>
</div>
</div>
</div>
</script>
<script type="text/x-template" title="movePageErrors">
<div id="move-errors" class="hidden warning"></div>
</script>
<script type="text/x-template" title="movePageBreadcrumb">
<li><a class="{2}" title="{3}" tabindex="-1"><span>{0}</span></a></li>
</script>
<script type="text/x-template" title="movePageBreadcrumbLoading">
<li class="loading"><span>Loading breadcrumbs&hellip;</span></li>
</script>
<script type="text/x-template" title="movePageBreadcrumbError">
<li class="warning last"><span>Error retrieving breadcrumbs.</span></li>
</script>
<script type="text/x-template" title="movePageNoMatchingPages">
<ol><li><span class="warning">No matching pages found.</span></li></ol>
</script>
<script type="text/x-template" title="movePageNoMatchingSpaces">
<ol><li><span class="warning">No matching spaces found.</span></li></ol>
</script>
<script type="text/x-template" title="movePageSearchPanel">
<div class="row information">
<div class="inner">
<div class="element">
Search for and select the new parent page for this page and its children.
</div>
</div>
</div>
<div id="move-page-search-container" class="row">
<div class="search-form">
<fieldset>
<legend class="assistive"><span>Search for a New Parent Page</span></legend>
<label for="move-page-search-query" class="assistive">Search keywords</label>
<input class="search-query" id="move-page-search-query">
<label for="move-page-search-space" class="assistive">Search in space</label>
<select id="move-page-search-space" class="search-space" disabled="disabled">
<option value="dubbo" selected="selected">Dubbo</option>
</select>
<input type="button" value="Search">
<div class="description warning">You cannot move this page to another space because you do not have permission to remove it from this space.</div>
</fieldset>
</div>
<div class="search-results">
</div>
</div>
</script>
<script type="text/x-template" title="movePageSearchResultsLoading">
<div class="searching">Searching…</div>
</script>
<script type="text/x-template" title="movePageHistoryPanel">
<div class="row information">
<div class="inner">
<div class="element">
Select the new parent page for this page and its children from your history.
</div>
</div>
</div>
<div id="move-page-search-container" class="row">
<div class="search-results">
</div>
</div>
</script>
<script type="text/x-template" title="movePageHistoryLoading">
<div class="searching">Loading…</div>
</script>
<script type="text/x-template" title="movePageBrowsePanel">
<div class="row information">
<div class="inner">
<div class="element">
Click to select the new parent page for this page and its children.
</div>
</div>
</div>
<div class="tree"></div>
</script>
<script type="text/x-template" title="movePagePanelLoading">
<span>Loading…</span>
</script>
<script type="text/x-template" title="movePageBrowsePanelSpace">
<ul><li id='tree-root-node-item' class='root-node-list-item'><a class='root-node' href='#'>{0}</a></li></ul>
</script>
<script type="text/x-template" title="orderingPagePanel">
<div id="orderingPlaceHolder"></div>
</script>
<script type="text/x-template" title="reorderCheckbox">
<span id="reorderRequirement"><input id="reorderCheck" type="checkbox" name="reorderFlag" title="Choose the position of this page within the list of child pages."/><label for="reorderCheck" title="Choose the position of this page within the list of child pages.">Reorder</label></span>
</script>
<script type="text/x-template" title="move-help-link">
<div class="dialog-help-link">
<a href="http://docs.atlassian.com/confluence/docs-35/Moving+a+Page" target="_blank">Help</a>
</div>
</script>
<script type="text/x-template" title="searchResultsGrid">
<table>
<thead>
<tr class="header">
<th class="search-result-title">Page Title</th>
<th class="search-result-space">Space</th>
<th class="search-result-date">Updated</th>
</tr>
</thead>
</table>
</script>
<script type="text/x-template" title="searchResultsGridCount">
<p class="search-result-count">{0}</p>
</script>
<script type="text/x-template" title="searchResultsGridRow">
<tr class="search-result">
<th class="search-result-title"><a href="{1}" class="content-type-{2}"><span>{0}</span></a></th>
<td class="search-result-space"><a class="space" href="http://10.20.160.198/wiki/display/{4}/" title="{3}">{3}</a></td>
<td class="search-result-date"><span class="date" title="{6}">{5}</span></td>
</tr>
</script>
<!-- Start restrictions section -->
<script type="text/x-template" title="page-permissions-div">
<div id="page-permissions-div">
<div id="page-permissions-editor-form">
<div id="page-permissions-error-div" class="hidden">
<a href="#" id="permissions-error-div-close">Ok</a>
<div></div>
</div>
<div id="page-permissions-type-radios" class="page-permissions-label-rows">
<div>
<input id="restrictViewRadio" type="radio" checked="checked" name="pagePermissionTypeRadio" value="view"/>
<label for="restrictViewRadio">Restrict viewing of this page</label>
<input id="restrictEditRadio" type="radio" name="pagePermissionTypeRadio" value="edit"/>
<label for="restrictEditRadio">Restrict editing of this page</label>
</div>
</div>
<div id="page-permissions-input" class="page-permissions-label-rows">
<div class="page-permissions-label">To:</div>
<div id="page-permissions-chooser-box">
<span id="page-permissions-choose-user" class="ajs-button">
<a href="#" id='userpicker-popup-link-image' onClick="var picker = window.open('http://10.20.160.198/wiki/spaces/openuserpicker.action?key=dubbo&startIndex=0&onPopupSubmit=AJS.PagePermissions.addUserPermissions', 'EntitiesPicker', 'status=yes,resizable=yes,top=100,left=200,width=700,height=680,scrollbars=yes'); picker.focus(); return false;"><img src="user_16.gif"/*tpa=http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/user_16.gif*/ height=16 width=16 border=0 align="absmiddle" title="Choose users" /></a>
<a href="#" id='userpicker-popup-link-text' onClick="var picker = window.open('http://10.20.160.198/wiki/spaces/openuserpicker.action?key=dubbo&startIndex=0&onPopupSubmit=AJS.PagePermissions.addUserPermissions', 'EntitiesPicker', 'status=yes,resizable=yes,top=100,left=200,width=700,height=680,scrollbars=yes'); picker.focus(); return false;">Person...</a>
</span>
<span id="page-permissions-choose-group" class="ajs-button">
<a href="#" id='grouppicker-popup-link-image' onClick="var picker = window.open('http://10.20.160.198/wiki/spaces/opengrouppicker.action?key=dubbo&startIndex=0&actionName=dosearchgroups.action&onPopupSubmit=AJS.PagePermissions.addGroupPermissions', 'EntitiesPicker', 'status=yes,resizable=yes,top=100,left=200,width=580,height=550,scrollbars=yes'); picker.focus(); return false;"><img src="group_16.gif"/*tpa=http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/group_16.gif*/ height=16 width=16 border=0 align="absmiddle" title="Choose groups" /></a>
<a href="#" id='grouppicker-popup-link-text' onClick="var picker = window.open('http://10.20.160.198/wiki/spaces/opengrouppicker.action?key=dubbo&startIndex=0&actionName=dosearchgroups.action&onPopupSubmit=AJS.PagePermissions.addGroupPermissions', 'EntitiesPicker', 'status=yes,resizable=yes,top=100,left=200,width=580,height=550,scrollbars=yes'); picker.focus(); return false;">Group...</a>
</span>
</div>
<div id="page-permissions-input-box">
<span>
<input type="text" id="page-permissions-names-input" class="input-placeholder" value="Enter user or group name" name="permissionNames" size="30" autocomplete="off"/>
</span>
<input
type="hidden"
id="page-permissions-names-hidden" /> <img height="16px" width="1px" src="spacer.gif"/*tpa=http://10.20.160.198/wiki/s/en/2166/34/_/images/border/spacer.gif*//>
<input type="button" id="add-typed-names" value="Restrict">
</div>
</div>
</div>
<div id="page-permissions-tables">
<div id="page-permissions-table-div">
<table id="page-permissions-table" class="page-permissions-table">
<tr id="page-permissions-no-views" class="marker-row">
<td colspan="3" class="page-permissions-marker-cell"><span>No view restrictions are defined for this page</span></td>
</tr>
<tr id="page-permissions-no-edits" class="marker-row">
<td colspan="3" class="page-permissions-marker-cell"><span>No edit restrictions are defined for this page</span></td>
</tr>
</table>
</div>
<div id="page-inherited-permissions-table-div" class="hidden">
<span id="page-inherited-permissions-table-desc">
<a class="icon twisty-closed">Show/Hide</a>
<a id="toggle-inherited-permissions" title="Click to see inherited restrictions">This page has restricted parent pages. It can only be seen by users who can see those parent pages.</a>
</span>
<div id="page-inherited-permissions-tables" class="hidden page-inheritance-togglable"></div>
</div>
</div>
</div>
</script>
<script type="text/x-template" title="permissions-row-template">
<tr class="permission-row">
<td class="page-permissions-marker-cell" width="20%">
<span>Viewing restricted to:</span>
</td>
<td class="permission-entity" nowrap="true" width="40%">
<span class="entity-container">
<img class="permission-entity-picture"/>
<span class="permission-entity-display-name"></span>
<span class="permission-entity-name-wrap">&nbsp;(<span class="permission-entity-name"></span>)</span>
</span>
</td>
<td class="permission-detail-column">
<div class="permission-remove-div">
<a href="#" class="remove-permission-link">Remove restriction</a>
</div>
</td>
</tr>
</script>
<script type="text/x-template" title="permissions-username-no-suggestion-template">
<ol>
<li><a href="#" class="message"><span>No matches</span></a></li>
</ol>
</script>
<script type="text/x-template" title="page-inherited-permissions-table-div-template">
<div class="page-inherited-permissions-owner-div">
<div class="page-inherited-permissions-table-desc">Viewing restrictions apply to “<a></a>”. In order to see “<span></span>”, a user must be in the following list of users and groups:</div>
<table class="page-permissions-table"></table>
</div>
</script>
<script type="text/x-template" title="page-restrictions-help-link">
<div class="dialog-help-link">
<a href="http://docs.atlassian.com/confluence/docs-35/Page+Restrictions" target="_blank">Help</a>
</div>
</script>
<!-- End restrictions section -->
<fieldset class="hidden parameters">
<input type="hidden" title="spaceKeyEncoded" value="dubbo">
<input type="hidden" title="spaceKeyDecoded" value="dubbo">
</fieldset>
<a href="#page-metadata-end" class="assistive">Skip to end of metadata</a>
<div id="page-metadata-start" class="assistive"></div>
<div class="page-metadata">
<ul>
<li class="page-metadata-item noprint">
<a id="content-metadata-page-restrictions" href="#" class="page-metadata-icon page-restrictions hidden" title="Page restrictions apply. Click the lock icon to view or edit the restriction.">
<span>Page restrictions apply</span></a> </li>
<li class="page-metadata-modification-info" style="display: none">
Added by <a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/~chao.liuc \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/~chao.liuc%27" tppabs="http://10.20.160.198/wiki/display/~chao.liuc"
class="url fn confluence-userlink" data-username="chao.liuc"
>刘 超</a>, last edited by <a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/~ding.lid \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/~ding.lid%27" tppabs="http://10.20.160.198/wiki/display/~ding.lid"
class="url fn confluence-userlink" data-username="ding.lid"
>李 鼎</a> on 十一月 27, 2012
<span class="noprint">&nbsp;(<a id="view-change-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/diffpages.action?pageId=6947109&originalId=8355859 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/diffpages.action?pageId=6947109&originalId=8355859%27" tppabs="http://10.20.160.198/wiki/pages/diffpages.action?pageId=6947109&originalId=8355859">view change</a>)</span>
</li>
</ul>
<div id="version-comment" class="noteMacro" style="display: none;">
<strong>Comment:</strong>
<br />
</div>
</div>
<a href="#page-metadata-start" class="assistive">Go to start of metadata</a>
<div id="page-metadata-end" class="assistive"></div>
<fieldset class="hidden parameters">
<input type="hidden" title="browsePageTreeMode" value="view">
<input type="hidden" title="parentPageId" value="6324288">
</fieldset>
<div class="wiki-content">
<!-- wiki content -->
<h2><a name="Examples-Examples"></a>Examples</h2>
<p>(<a href="Examples.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Examples" title="Examples">+</a>) (<a href="#Examples-Examples">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>想完整的运行起来,请参见:<a href="#Examples-QuickStart">Quick Start</a> (<a href="Quick+Start.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Quick+Start" title="Quick Start">+</a>),这里只列出各种场景的配置方式</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>以下示例全部使用基于Spring的<a href="#Examples-XmlConfig">Xml Config</a> (<a href="Xml+Config.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Xml+Config" title="Xml Config">+</a>)作为参考,如果不想使用Spring,而希望通过API的方式进行调用,请参见:<a href="#Examples-APIConfig">API Config</a> (<a href="API+Config.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/API+Config" title="API Config">+</a>)</td></tr></table></div>
<h3><a name="Examples-CheckOnStartup"></a>Check On Startup</h3>
<p>(<a href="Check+On+Startup.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Check+On+Startup" title="Check On Startup">+</a>) (<a href="#Examples-CheckOnStartup">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Dubbo缺省会在启动时检查依赖的服务是否可用,不可用时会抛出异常,阻止Spring初始化完成,以便上线时,能及早发现问题,默认check=true。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>如果你的Spring容器是懒加载的,或者通过API编程延迟引用服务,请关闭check,否则服务临时不可用时,会抛出异常,拿到null引用,如果check=false,总是会返回引用,当服务恢复时,能自动连上。</td></tr></table></div>
<p>可以通过check="false"关闭检查,比如,测试时,有些服务不关心,或者出现了循环依赖,必须有一方先启动。</p>
<p>关闭某个服务的启动时检查:(没有提供者时报错)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" check="false" /&gt;]]></script>
</div></div>
<p>关闭所有服务的启动时检查:(没有提供者时报错)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:consumer check="false" /&gt;]]></script>
</div></div>
<p>关闭注册中心启动时检查:(注册订阅失败时报错)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry check="false" /&gt;]]></script>
</div></div>
<p>也可以用dubbo.properties配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dubbo.properties</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: text; gutter: false"><![CDATA[dubbo.reference.com.foo.BarService.check=false
dubbo.reference.check=false
dubbo.consumer.check=false
dubbo.registry.check=false]]></script>
</div></div>
<p>也可以用-D参数:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: text; gutter: false"><![CDATA[java -Ddubbo.reference.com.foo.BarService.check=false
java -Ddubbo.reference.check=false
java -Ddubbo.consumer.check=false
java -Ddubbo.registry.check=false]]></script>
</div></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>注意区别</b><br /><ul>
<li>dubbo.reference.check=false,强制改变所有reference的check值,就算配置中有声明,也会被覆盖。</li>
<li>dubbo.consumer.check=false,是设置check的缺省值,如果配置中有显式的声明,如:&lt;dubbo:reference check="true"/&gt;,不会受影响。</li>
<li>dubbo.registry.check=false,前面两个都是指订阅成功,但提供者列表是否为空时是否报错,如果注册订阅失败时,也允许启动,需使用此选项,将在后台定时重试。</li>
</ul>
</td></tr></table></div>
<p>引用缺省是延迟初始化的,只有引用被注入到其它Bean,或被getBean()获取,才会初始化。<br/>
如果需要饥饿加载,即没有人引用也立即生成动态代理,可以配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" init="true" /&gt;]]></script>
</div></div>
<h3><a name="Examples-FaultTolerance"></a>Fault Tolerance</h3>
<p>(<a href="Fault+Tolerance.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Fault+Tolerance" title="Fault Tolerance">+</a>) (<a href="#Examples-FaultTolerance">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>在集群调用失败时,Dubbo提供了多种容错方案,缺省为failover重试。</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="cluster.jpg-version=1&modificationDate=1321028038000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949932/cluster.jpg?version=1&modificationDate=1321028038000" style="border: 0px solid black" /></span></p>
<p><b>各节点关系:</b></p>
<ul>
<li>这里的Invoker是Provider的一个可调用Service的抽象,Invoker封装了Provider地址及Service接口信息。</li>
<li>Directory代表多个Invoker,可以把它看成List&lt;Invoker&gt;,但与List不同的是,它的值可能是动态变化的,比如注册中心推送变更。</li>
<li>Cluster将Directory中的多个Invoker伪装成一个Invoker,对上层透明,伪装过程包含了容错逻辑,调用失败后,重试另一个。</li>
<li>Router负责从多个Invoker中按路由规则选出子集,比如读写分离,应用隔离等。</li>
<li>LoadBalance负责从多个Invoker中选出具体的一个用于本次调用,选的过程包含了负载均衡算法,调用失败后,需要重选。</li>
</ul>
<h5><a name="Examples-%E9%9B%86%E7%BE%A4%E5%AE%B9%E9%94%99%E6%A8%A1%E5%BC%8F%EF%BC%9A"></a>集群容错模式:</h5>
<p>可以自行扩展集群容错策略,参见:<a href="Developer+Guide.htm#DeveloperGuide-ClusterSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-ClusterSPI">Cluster SPI</a></p>
<h6><a name="Examples-FailoverCluster"></a>Failover Cluster</h6>
<ul>
<li>失败自动切换,当出现失败,重试其它服务器。(缺省)</li>
<li>通常用于读操作,但重试会带来更长延迟。</li>
<li>可通过retries="2"来设置重试次数(不含第一次)。</li>
</ul>
<h6><a name="Examples-FailfastCluster"></a>Failfast Cluster</h6>
<ul>
<li>快速失败,只发起一次调用,失败立即报错。</li>
<li>通常用于非幂等性的写操作,比如新增记录。</li>
</ul>
<h6><a name="Examples-FailsafeCluster"></a>Failsafe Cluster</h6>
<ul>
<li>失败安全,出现异常时,直接忽略。</li>
<li>通常用于写入审计日志等操作。</li>
</ul>
<h6><a name="Examples-FailbackCluster"></a>Failback Cluster</h6>
<ul>
<li>失败自动恢复,后台记录失败请求,定时重发。</li>
<li>通常用于消息通知操作。</li>
</ul>
<h6><a name="Examples-ForkingCluster"></a>Forking Cluster</h6>
<ul>
<li>并行调用多个服务器,只要一个成功即返回。</li>
<li>通常用于实时性要求较高的读操作,但需要浪费更多服务资源。</li>
<li>可通过forks="2"来设置最大并行数。</li>
</ul>
<h6><a name="Examples-BroadcastCluster"></a>Broadcast Cluster</h6>
<ul>
<li>广播调用所有提供者,逐个调用,任意一台报错则报错。(2.1.0开始支持)</li>
<li>通常用于通知所有提供者更新缓存或日志等本地资源信息。</li>
</ul>
<p>重试次数配置如:(failover集群模式生效)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service retries="2" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference retries="2" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference&gt;
&lt;dubbo:method name="findFoo" retries="2" /&gt;
&lt;/dubbo:reference&gt;]]></script>
</div></div>
<p>集群模式配置如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service cluster="failsafe" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference cluster="failsafe" /&gt;]]></script>
</div></div>
<h3><a name="Examples-LoadBalance"></a>Load Balance</h3>
<p>(<a href="Load+Balance.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Load+Balance" title="Load Balance">+</a>) (<a href="#Examples-LoadBalance">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>在集群负载均衡时,Dubbo提供了多种均衡策略,缺省为random随机调用。</td></tr></table></div>
<p>可以自行扩展负载均衡策略,参见:<a href="Developer+Guide.htm#DeveloperGuide-LoadBalanceSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-LoadBalanceSPI">LoadBalance SPI</a></p>
<h6><a name="Examples-RandomLoadBalance"></a>Random LoadBalance</h6>
<ul>
<li>随机,按权重设置随机概率。</li>
<li>在一个截面上碰撞的概率高,但调用量越大分布越均匀,而且按概率使用权重后也比较均匀,有利于动态调整提供者权重。</li>
</ul>
<h6><a name="Examples-RoundRobinLoadBalance"></a>RoundRobin LoadBalance</h6>
<ul>
<li>轮循,按公约后的权重设置轮循比率。</li>
<li>存在慢的提供者累积请求问题,比如:第二台机器很慢,但没挂,当请求调到第二台时就卡在那,久而久之,所有请求都卡在调到第二台上。</li>
</ul>
<h6><a name="Examples-LeastActiveLoadBalance"></a>LeastActive LoadBalance</h6>
<ul>
<li>最少活跃调用数,相同活跃数的随机,活跃数指调用前后计数差。</li>
<li>使慢的提供者收到更少请求,因为越慢的提供者的调用前后计数差会越大。</li>
</ul>
<h6><a name="Examples-ConsistentHashLoadBalance"></a>ConsistentHash LoadBalance</h6>
<ul>
<li>一致性Hash,相同参数的请求总是发到同一提供者。</li>
<li>当某一台提供者挂时,原本发往该提供者的请求,基于虚拟节点,平摊到其它提供者,不会引起剧烈变动。</li>
<li>算法参见:<a href="javascript:if(confirm(%27http://en.wikipedia.org/wiki/Consistent_hashing \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://en.wikipedia.org/wiki/Consistent_hashing%27" tppabs="http://en.wikipedia.org/wiki/Consistent_hashing" class="external-link" rel="nofollow">http://en.wikipedia.org/wiki/Consistent_hashing</a></li>
<li>缺省只对第一个参数Hash,如果要修改,请配置&lt;dubbo:parameter key="hash.arguments" value="0,1" /&gt;</li>
<li>缺省用160份虚拟节点,如果要修改,请配置&lt;dubbo:parameter key="hash.nodes" value="320" /&gt;</li>
</ul>
<p>配置如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="..." loadbalance="roundrobin" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="..." loadbalance="roundrobin" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="..."&gt;
&lt;dubbo:method name="..." loadbalance="roundrobin"/&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="..."&gt;
&lt;dubbo:method name="..." loadbalance="roundrobin"/&gt;
&lt;/dubbo:reference&gt;]]></script>
</div></div>
<h3><a name="Examples-ThreadModel"></a>Thread Model</h3>
<p>(<a href="Thread+Model.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Thread+Model" title="Thread Model">+</a>) (<a href="#Examples-ThreadModel">#</a>)</p>
<p><span class="image-wrap" style=""><img src="dubbo-protocol.jpg-version=1&modificationDate=1331068241000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949458/dubbo-protocol.jpg?version=1&modificationDate=1331068241000" style="border: 0px solid black" /></span></p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>事件处理线程说明</b><br /><ul>
<li>如果事件处理的逻辑能迅速完成,并且不会发起新的IO请求,比如只是在内存中记个标识,则直接在IO线程上处理更快,因为减少了线程池调度。</li>
<li>但如果事件处理逻辑较慢,或者需要发起新的IO请求,比如需要查询数据库,则必须派发到线程池,否则IO线程阻塞,将导致不能接收其它请求。</li>
<li>如果用IO线程处理事件,又在事件处理过程中发起新的IO请求,比如在连接事件中发起登录请求,会报“可能引发死锁”异常,但不会真死锁。</li>
</ul>
</td></tr></table></div>
<ul>
<li>Dispatcher
<ul>
<li>all 所有消息都派发到线程池,包括请求,响应,连接事件,断开事件,心跳等。</li>
<li>direct 所有消息都不派发到线程池,全部在IO线程上直接执行。</li>
<li>message 只有请求响应消息派发到线程池,其它连接断开事件,心跳等消息,直接在IO线程上执行。</li>
<li>execution 只请求消息派发到线程池,不含响应,响应和其它连接断开事件,心跳等消息,直接在IO线程上执行。</li>
<li>connection 在IO线程上,将连接断开事件放入队列,有序逐个执行,其它消息派发到线程池。</li>
</ul>
</li>
</ul>
<ul>
<li>ThreadPool
<ul>
<li>fixed 固定大小线程池,启动时建立线程,不关闭,一直持有。(缺省)</li>
<li>cached 缓存线程池,空闲一分钟自动删除,需要时重建。</li>
<li>limited 可伸缩线程池,但池中的线程数只会增长不会收缩。(为避免收缩时突然来了大流量引起的性能问题)。</li>
</ul>
</li>
</ul>
<p>配置如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="dubbo" dispatcher="all" threadpool="fixed" threads="100" /&gt;]]></script>
</div></div>
<h3><a name="Examples-DirectlyProvider"></a>Directly Provider</h3>
<p>(<a href="Directly+Provider.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Directly+Provider" title="Directly Provider">+</a>) (<a href="#Examples-DirectlyProvider">#</a>)</p>
<p>在开发及测试环境下,经常需要绕过注册中心,只测试指定服务提供者,这时候可能需要点对点直连,<br/>
点对点直联方式,将以服务接口为单位,忽略注册中心的提供者列表,<br/>
A接口配置点对点,不影响B接口从注册中心获取列表。</p>
<p><span class="image-wrap" style=""><img src="dubbo-directly.jpg-version=1&modificationDate=1326853485000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949440/dubbo-directly.jpg?version=1&modificationDate=1326853485000" style="border: 0px solid black" /></span></p>
<p>(1) 如果是线上需求需要点对点,可在&lt;dubbo:reference&gt;中配置url指向提供者,将绕过注册中心,<b>多个地址用分号隔开</b>,配置如下:(1.0.6及以上版本支持)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[&lt;dubbo:reference id="xxxService" interface="com.alibaba.xxx.XxxService" url="dubbo://localhost:20890" /&gt;]]></script>
</div></div>
<p>(2) 在JVM启动参数中加入-D参数映射服务地址(<font color="red">只应在测试阶段使用,请不要在线上这样使用</font>),如:<br/>
(key为服务名,value为服务提供者url,此配置优先级最高,1.0.15及以上版本支持)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java -Dcom.alibaba.xxx.XxxService=dubbo://localhost:20890]]></script>
</div></div>
<p>(3) 如果服务比较多,也可以用文件映射(<font color="red">只应在测试阶段使用,请不要在线上这样使用</font>),如:<br/>
(用-Ddubbo.resolve.file指定映射文件路径,此配置优先级高于&lt;dubbo:reference&gt;中的配置,1.0.15及以上版本支持)<br/>
(2.0以上版本自动加载${user.home}/dubbo-resolve.properties文件,不需要配置)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java -Ddubbo.resolve.file=xxx.properties]]></script>
</div></div>
<p>然后在映射文件xxx.properties中加入:<br/>
(key为服务名,value为服务提供者url)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[com.alibaba.xxx.XxxService=dubbo://localhost:20890]]></script>
</div></div>
<h3><a name="Examples-SubscribeOnly"></a>Subscribe Only</h3>
<p>(<a href="Subscribe+Only.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Subscribe+Only" title="Subscribe Only">+</a>) (<a href="#Examples-SubscribeOnly">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>问题</b><br />为方便开发测试,经常会在线下共用一个所有服务可用的注册中心,这时,如果一个正在开发中的服务提供者注册,可能会影响消费者不能正常运行。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>解决方案</b><br />可以让服务提供者开发方,只订阅服务(开发的服务可能依赖其它服务),而不注册正在开发的服务,通过直连测试正在开发的服务。</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="subscribe-only.jpg-version=1&modificationDate=1326468174000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949667/subscribe-only.jpg?version=1&modificationDate=1326468174000" style="border: 0px solid black" /></span></p>
<p>禁用注册配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry address="10.20.153.10:9090" register="false" /&gt;]]></script>
</div></div>
<p>或者:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry address="10.20.153.10:9090?register=false" /&gt;]]></script>
</div></div>
<h3><a name="Examples-RegisterOnly"></a>Register Only</h3>
<p>(<a href="Register+Only.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Register+Only" title="Register Only">+</a>) (<a href="#Examples-RegisterOnly">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>问题</b><br />如果有两个镜像环境,两个注册中心,有一个服务只在其中一个注册中心有部署,另一个注册中心还没来得及部署,而两个注册中心的其它应用都需要依赖此服务,所以需要将服务同时注册到两个注册中心,但却不能让此服务同时依赖两个注册中心的其它服务。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>解决方案</b><br />可以让服务提供者方,只注册服务到另一注册中心,而不从另一注册中心订阅服务。</td></tr></table></div>
<p>禁用订阅配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry id="hzRegistry" address="10.20.153.10:9090" /&gt;
&lt;dubbo:registry id="qdRegistry" address="10.20.141.150:9090" subscribe="false" /&gt;]]></script>
</div></div>
<p>或者:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry id="hzRegistry" address="10.20.153.10:9090" /&gt;
&lt;dubbo:registry id="qdRegistry" address="10.20.141.150:9090?subscribe=false" /&gt;]]></script>
</div></div>
<h3><a name="Examples-StaticProvider"></a>Static Provider</h3>
<p>(<a href="Static+Provider.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Static+Provider" title="Static Provider">+</a>) (<a href="#Examples-StaticProvider">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>有时候希望人工管理服务提供者的上线和下线,此时需将注册中心标识为非动态管理模式。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry address="10.20.141.150:9090" dynamic="false" /&gt;]]></script>
</div></div>
<p>或者:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:registry address="10.20.141.150:9090?dynamic=false" /&gt;]]></script>
</div></div>
<p>服务提供者初次注册时为禁用状态,需人工启用,断线时,将不会被自动删除,需人工禁用。</p>
<p>如果是一个第三方独立提供者,比如memcached等,可以直接向注册中心写入提供者地址信息,消费者正常使用:<br/>
(通常由脚本监控中心页面等调用)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("memcached://10.20.153.11/com.foo.BarService?category=providers&amp;dynamic=false&amp;application=foo"));]]></script>
</div></div>
<h3><a name="Examples-MultiProtocol"></a>Multi Protocol</h3>
<p>(<a href="Multi+Protocol.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Protocol" title="Multi Protocol">+</a>) (<a href="#Examples-MultiProtocol">#</a>)</p>
<p>可以自行扩展协议,参见:<a href="Developer+Guide.htm#DeveloperGuide-ProtocolSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-ProtocolSPI">Protocol SPI</a></p>
<h4><a name="Examples-%281%29%E4%B8%8D%E5%90%8C%E6%9C%8D%E5%8A%A1%E4%B8%8D%E5%90%8C%E5%8D%8F%E8%AE%AE"></a>(1) 不同服务不同协议</h4>
<p>比如:不同服务在性能上适用不同协议进行传输,比如大数据用短连接协议,小数据大并发用长连接协议。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;dubbo:registry id="registry" address="10.20.141.150:9090" username="admin" password="hello1234" /&gt;
&lt;!-- 多协议配置 --&gt;
&lt;dubbo:protocol name="dubbo" port="20880" /&gt;
&lt;dubbo:protocol name="rmi" port="1099" /&gt;
&lt;!-- 使用dubbo协议暴露服务 --&gt;
&lt;dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" protocol="dubbo" /&gt;
&lt;!-- 使用rmi协议暴露服务 --&gt;
&lt;dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" protocol="rmi" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<h4><a name="Examples-%282%29%E5%A4%9A%E5%8D%8F%E8%AE%AE%E6%9A%B4%E9%9C%B2%E6%9C%8D%E5%8A%A1"></a>(2) 多协议暴露服务</h4>
<p>比如:需要与http客户端互操作</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;dubbo:registry id="registry" address="10.20.141.150:9090" username="admin" password="hello1234" /&gt;
&lt;!-- 多协议配置 --&gt;
&lt;dubbo:protocol name="dubbo" port="20880" /&gt;
&lt;dubbo:protocol name="hessian" port="8080" /&gt;
&lt;!-- 使用多个协议暴露服务 --&gt;
&lt;dubbo:service id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" protocol="dubbo,hessian" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<h3><a name="Examples-MultiRegistry"></a>Multi Registry</h3>
<p>(<a href="Multi+Registry.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Registry" title="Multi Registry">+</a>) (<a href="#Examples-MultiRegistry">#</a>)</p>
<p>可以自行扩展注册中心,参见:<a href="Developer+Guide.htm#DeveloperGuide-RegistrySPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-RegistrySPI">Registry SPI</a></p>
<h4><a name="Examples-%281%29%E5%A4%9A%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83%E6%B3%A8%E5%86%8C"></a>(1) 多注册中心注册</h4>
<p>比如:中文站有些服务来不及在青岛部署,只在杭州部署,而青岛的其它应用需要引用此服务,就可以将服务同时注册到两个注册中心。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;!-- 多注册中心配置 --&gt;
&lt;dubbo:registry id="hangzhouRegistry" address="10.20.141.150:9090" /&gt;
&lt;dubbo:registry id="qingdaoRegistry" address="10.20.141.151:9010" default="false" /&gt;
&lt;!-- 向多个注册中心注册 --&gt;
&lt;dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="hangzhouRegistry,qingdaoRegistry" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<h4><a name="Examples-%282%29%E4%B8%8D%E5%90%8C%E6%9C%8D%E5%8A%A1%E4%BD%BF%E7%94%A8%E4%B8%8D%E5%90%8C%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83"></a>(2) 不同服务使用不同注册中心</h4>
<p>比如:CRM有些服务是专门为国际站设计的,有些服务是专门为中文站设计的。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;!-- 多注册中心配置 --&gt;
&lt;dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" /&gt;
&lt;dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" /&gt;
&lt;!-- 向中文站注册中心注册 --&gt;
&lt;dubbo:service interface="com.alibaba.hello.api.HelloService" version="1.0.0" ref="helloService" registry="chinaRegistry" /&gt;
&lt;!-- 向国际站注册中心注册 --&gt;
&lt;dubbo:service interface="com.alibaba.hello.api.DemoService" version="1.0.0" ref="demoService" registry="intlRegistry" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<h4><a name="Examples-%283%29%E5%A4%9A%E6%B3%A8%E5%86%8C%E4%B8%AD%E5%BF%83%E5%BC%95%E7%94%A8"></a>(3) 多注册中心引用</h4>
<p>比如:CRM需同时调用中文站和国际站的PC2服务,PC2在中文站和国际站均有部署,接口及版本号都一样,但连的数据库不一样。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;!-- 多注册中心配置 --&gt;
&lt;dubbo:registry id="chinaRegistry" address="10.20.141.150:9090" /&gt;
&lt;dubbo:registry id="intlRegistry" address="10.20.154.177:9010" default="false" /&gt;
&lt;!-- 引用中文站服务 --&gt;
&lt;dubbo:reference id="chinaHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="chinaRegistry" /&gt;
&lt;!-- 引用国际站站服务 --&gt;
&lt;dubbo:reference id="intlHelloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" registry="intlRegistry" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<p>如果只是测试环境临时需要连接两个不同注册中心,使用竖号分隔多个不同注册中心地址:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;?xml version="1.0" encoding="UTF-8"?&gt;
&lt;beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:dubbo="http://code.alibabatech.com/schema/dubbo"
xsi:schemaLocation="http://www.springframework.org/schema/beanshttp://www.springframework.org/schema/beans/spring-beans.xsdhttp://code.alibabatech.com/schema/dubbohttp://code.alibabatech.com/schema/dubbo/dubbo.xsd"&gt;
&lt;dubbo:application name="world" /&gt;
&lt;!-- 多注册中心配置,竖号分隔表示同时连接多个不同注册中心,同一注册中心的多个集群地址用逗号分隔 --&gt;
&lt;dubbo:registry address="10.20.141.150:9090|10.20.154.177:9010" /&gt;
&lt;!-- 引用服务 --&gt;
&lt;dubbo:reference id="helloService" interface="com.alibaba.hello.api.HelloService" version="1.0.0" /&gt;
&lt;/beans&gt;]]></script>
</div></div>
<h3><a name="Examples-MultiGroup"></a>Multi Group</h3>
<p>(<a href="Multi+Group.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Group" title="Multi Group">+</a>) (<a href="#Examples-MultiGroup">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>当一个接口有多种实现时,可以用group区分。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service group="feedback" interface="com.xxx.IndexService" /&gt;
&lt;dubbo:service group="member" interface="com.xxx.IndexService" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="feedbackIndexService" group="feedback" interface="com.xxx.IndexService" /&gt;
&lt;dubbo:reference id="memberIndexService" group="member" interface="com.xxx.IndexService" /&gt;]]></script>
</div></div>
<p>任意组:(2.2.0以上版本支持,总是只调一个可用组的实现)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="barService" interface="com.foo.BarService" group="*" /&gt;]]></script>
</div></div>
<h3><a name="Examples-MultiVersion"></a>Multi Version</h3>
<p>(<a href="Multi+Version.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Version" title="Multi Version">+</a>) (<a href="#Examples-MultiVersion">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>当一个接口实现,出现不兼容升级时,可以用版本号过渡,版本号不同的服务相互间不引用。</td></tr></table></div>
<ul>
<li>在低压力时间段,先升级一半提供者为新版本</li>
<li>再将所有消费者升级为新版本</li>
<li>然后将剩下的一半提供者升级为新版本</li>
</ul>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" version="1.0.0" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" version="2.0.0" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="barService" interface="com.foo.BarService" version="1.0.0" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="barService" interface="com.foo.BarService" version="2.0.0" /&gt;]]></script>
</div></div>
<p>不区分版本:(2.2.0以上版本支持)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="barService" interface="com.foo.BarService" version="*" /&gt;]]></script>
</div></div>
<h3><a name="Examples-MergeByGroup"></a>Merge By Group</h3>
<p>(<a href="Merge+By+Group.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Merge+By+Group" title="Merge By Group">+</a>) (<a href="#Examples-MergeByGroup">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>按组合并返回结果,比如菜单服务,接口一样,但有多种实现,用group区分,现在消费方需从每种group中调用一次返回结果,合并结果返回,这样就可以实现聚合菜单项。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>从2.1.0版本开始支持</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="dubbo-merger.jpg-version=1&modificationDate=1329310196000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6952105/dubbo-merger.jpg?version=1&modificationDate=1329310196000" style="border: 0px solid black" /></span></p>
<p>代码参见:<a href="javascript:if(confirm(%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge%27" tppabs="http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge" class="external-link" rel="nofollow">http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/merge</a></p>
<p>配置如:(搜索所有分组)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="*" merger="true" /&gt;]]></script>
</div></div>
<p>或:(合并指定分组)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="aaa,bbb" merger="true" /&gt;]]></script>
</div></div>
<p>或:(指定方法合并结果,其它未指定的方法,将只调用一个Group)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="*"&gt;
&lt;dubbo:method name="getMenuItems" merger="true" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>或:(某个方法不合并结果,其它都合并结果)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="*" merger="true"&gt;
&lt;dubbo:method name="getMenuItems" merger="false" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>或:(指定合并策略,缺省根据返回值类型自动匹配,如果同一类型有两个合并器时,需指定合并器的名称)<br/>
参见:<a href="Developer+Guide.htm#DeveloperGuide-MergerSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-MergerSPI">Merger SPI</a></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="*"&gt;
&lt;dubbo:method name="getMenuItems" merger="mymerge" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>或:(指定合并方法,将调用返回结果的指定方法进行合并,合并方法的参数类型必须是返回结果类型本身)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.xxx.MenuService" group="*"&gt;
&lt;dubbo:method name="getMenuItems" merger=".addAll" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<h3><a name="Examples-ParameterValidation"></a>Parameter Validation</h3>
<p>(<a href="Parameter+Validation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Parameter+Validation" title="Parameter Validation">+</a>) (<a href="#Examples-ParameterValidation">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>参数验证功能是基于<a href="javascript:if(confirm(%27http://jcp.org/en/jsr/detail?id=303 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://jcp.org/en/jsr/detail?id=303%27" tppabs="http://jcp.org/en/jsr/detail?id=303" class="external-link" rel="nofollow">JSR303</a>实现的,用户只需标识JSR303标准的验证Annotation,并通过声明filter来实现验证。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.1.0以上版本支持</td></tr></table></div>
<p>完整示例代码参见:<a href="javascript:if(confirm(%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation%27" tppabs="http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation" class="external-link" rel="nofollow">http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/validation</a></p>
<p>验证方式可扩展,参见:<a href="Developer+Guide.htm#DeveloperGuide-Validation" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-Validation">Validation扩展点</a></p>
<p>参数标注示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[import java.io.Serializable;
import java.util.Date;
import javax.validation.constraints.Future;
import javax.validation.constraints.Max;
import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
import javax.validation.constraints.Past;
import javax.validation.constraints.Pattern;
import javax.validation.constraints.Size;
public class ValidationParameter implements Serializable {
private static final long serialVersionUID = 7158911668568000392L;
@NotNull // 不允许为空
@Size(min = 1, max = 20) // 长度或大小范围
private String name;
@NotNull(groups = ValidationService.Save.class) // 保存时不允许为空,更新时允许为空 ,表示不更新该字段
@Pattern(regexp = "^\\s*\\w+(?:\\.{0,1}[\\w-]+)*@[a-zA-Z0-9]+(?:[-.][a-zA-Z0-9]+)*\\.[a-zA-Z]+\\s*$")
private String email;
@Min(18) // 最小值
@Max(100) // 最大值
private int age;
@Past // 必须为一个过去的时间
private Date loginDate;
@Future // 必须为一个未来的时间
private Date expiryDate;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public int getAge() {
return age;
}
public void setAge(int age) {
this.age = age;
}
public Date getLoginDate() {
return loginDate;
}
public void setLoginDate(Date loginDate) {
this.loginDate = loginDate;
}
public Date getExpiryDate() {
return expiryDate;
}
public void setExpiryDate(Date expiryDate) {
this.expiryDate = expiryDate;
}
}]]></script>
</div></div>
<p>分组验证示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[public interface ValidationService { // 缺省可按服务接口区分验证场景,如:@NotNull(groups = ValidationService.class)
@interface Save{} // 与方法同名接口,首字母大写,用于区分验证场景,如:@NotNull(groups = ValidationService.Save.class),可选
void save(ValidationParameter parameter);
void update(ValidationParameter parameter);
}]]></script>
</div></div>
<p>关联验证示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[import javax.validation.GroupSequence;
public interface ValidationService {
@GroupSequence(Update.class) // 同时验证Update组规则
@interface Save{}
void save(ValidationParameter parameter);
@interface Update{}
void update(ValidationParameter parameter);
}]]></script>
</div></div>
<p>参数验证示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[import javax.validation.constraints.Min;
import javax.validation.constraints.NotNull;
public interface ValidationService {
void save(@NotNull ValidationParameter parameter); // 验证参数不为空
void delete(@Min(1) int id); // 直接对基本类型参数验证
}]]></script>
</div></div>
<p>在客户端验证参数:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="validationService" interface="com.alibaba.dubbo.examples.validation.api.ValidationService" validation="true" /&gt;]]></script>
</div></div>
<p>在服务器端验证参数:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.alibaba.dubbo.examples.validation.api.ValidationService" ref="validationService" validation="true" /&gt;]]></script>
</div></div>
<p>验证异常信息:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[import javax.validation.ConstraintViolationException;
import javax.validation.ConstraintViolationException;
import org.springframework.context.support.ClassPathXmlApplicationContext;
import com.alibaba.dubbo.examples.validation.api.ValidationParameter;
import com.alibaba.dubbo.examples.validation.api.ValidationService;
import com.alibaba.dubbo.rpc.RpcException;
public class ValidationConsumer {
public static void main(String[] args) throws Exception {
String config = ValidationConsumer.class.getPackage().getName().replace('.', '/') + "/validation-consumer.xml";
ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext(config);
context.start();
ValidationService validationService = (ValidationService)context.getBean("validationService");
// Error
try {
parameter = new ValidationParameter();
validationService.save(parameter);
System.out.println("Validation ERROR");
} catch (RpcException e) { // 抛出的是RpcException
ConstraintViolationException ve = (ConstraintViolationException) e.getCause(); // 里面嵌了一个ConstraintViolationException
Set&lt;ConstraintViolation&lt;?&gt;&gt; violations = ve.getConstraintViolations(); // 可以拿到一个验证错误详细信息的集合
System.out.println(violations);
}
}
}]]></script>
</div></div>
<p>需要加入依赖:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dependency&gt;
&lt;groupId&gt;javax.validation&lt;/groupId&gt;
&lt;artifactId&gt;validation-api&lt;/artifactId&gt;
&lt;version&gt;1.0.0.GA&lt;/version&gt;
&lt;/dependency&gt;
&lt;dependency&gt;
&lt;groupId&gt;org.hibernate&lt;/groupId&gt;
&lt;artifactId&gt;hibernate-validator&lt;/artifactId&gt;
&lt;version&gt;4.2.0.Final&lt;/version&gt;
&lt;/dependency&gt;]]></script>
</div></div>
<h3><a name="Examples-ResultCache"></a>Result Cache</h3>
<p>(<a href="Result+Cache.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Result+Cache" title="Result Cache">+</a>) (<a href="#Examples-ResultCache">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>结果缓存,用于加速热门数据的访问速度,Dubbo提供声明式缓存,以减少用户加缓存的工作量。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.1.0以上版本支持</td></tr></table></div>
<p>示例代码:<a href="javascript:if(confirm(%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache%27" tppabs="http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache" class="external-link" rel="nofollow">http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/cache</a></p>
<ul>
<li>lru 基于最近最少使用原则删除多余缓存,保持最热的数据被缓存。</li>
<li>threadlocal 当前线程缓存,比如一个页面渲染,用到很多portal,每个portal都要去查用户信息,通过线程缓存,可以减少这种多余访问。</li>
<li>jcache 与<a href="javascript:if(confirm(%27http://jcp.org/en/jsr/detail?id=107 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://jcp.org/en/jsr/detail?id=107%27" tppabs="http://jcp.org/en/jsr/detail?id=107" class="external-link" rel="nofollow">JSR107</a>集成,可以桥接各种缓存实现。</li>
</ul>
<p>缓存类型可扩展,参见:<a href="Developer+Guide.htm#DeveloperGuide-CacheFactory" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-CacheFactory">CacheFactory扩展点</a></p>
<p>配置如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" cache="lru" /&gt;]]></script>
</div></div>
<p>或:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService"&gt;
&lt;dubbo:method name="findBar" cache="lru" /&gt;
&lt;/dubbo:reference&gt;]]></script>
</div></div>
<h3><a name="Examples-GenericReference"></a>Generic Reference</h3>
<p>(<a href="Generic+Reference.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Generic+Reference" title="Generic Reference">+</a>) (<a href="#Examples-GenericReference">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>泛接口调用方式主要用于客户端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的服务测试框架,可通过GenericService调用所有服务实现。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="barService" interface="com.foo.BarService" generic="true" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[GenericService barService = (GenericService) applicationContext.getBean("barService");
Object result = barService.$invoke("sayHello", new String[] { "java.lang.String" }, new Object[] { "World" });]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[import com.alibaba.dubbo.rpc.service.GenericService;
...
// 引用远程服务
ReferenceConfig&lt;GenericService&gt; reference = new ReferenceConfig&lt;GenericService&gt;(); // 该实例很重量,里面封装了所有与注册中心及服务提供方连接,请缓存
reference.setInterface("com.xxx.XxxService"); // 弱类型接口名
reference.setVersion("1.0.0");
reference.setGeneric(true); // 声明为泛化接口
GenericService genericService = reference.get(); // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口引用
// 基本类型以及Date,List,Map等不需要转换,直接调用
Object result = genericService.$invoke("sayHello", new String[] {"java.lang.String"}, new Object[] {"world"});
// 用Map表示POJO参数,如果返回值为POJO也将自动转成Map
Map&lt;String, Object&gt; person = new HashMap&lt;String, Object&gt;();
person.put("name", "xxx");
person.put("password", "yyy");
Object result = genericService.$invoke("findPerson", new String[]{"com.xxx.Person"}, new Object[]{person}); // 如果返回POJO将自动转成Map
...]]></script>
</div></div>
<p>假设存在POJO如: </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.xxx;
public class PersonImpl implements Person {
private String name;
private String password;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password= password;
}
}]]></script>
</div></div>
<p>则POJO数据: </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[Person person = new PersonImpl();
person.setName("xxx");
person.setPassword("yyy");]]></script>
</div></div>
<p>可用下面Map表示: </p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[Map&lt;String, Object&gt; map = new HashMap&lt;String, Object&gt;();
map.put("class", "com.xxx.PersonImpl"); // 注意:如果参数类型是接口,或者List等丢失泛型,可通过class属性指定类型。
map.put("name", "xxx");
map.put("password", "yyy");]]></script>
</div></div>
<h3><a name="Examples-GenericImplementation"></a>Generic Implementation</h3>
<p>(<a href="Generic+Implementation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Generic+Implementation" title="Generic Implementation">+</a>) (<a href="#Examples-GenericImplementation">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>泛接口实现方式主要用于服务器端没有API接口及模型类元的情况,参数及返回值中的所有POJO均用Map表示,通常用于框架集成,比如:实现一个通用的远程服务Mock框架,可通过实现GenericService接口处理所有服务请求。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;bean id="genericService" class="com.foo.MyGenericService" /&gt;
&lt;dubbo:service interface="com.foo.BarService" ref="genericService" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.foo;
public class MyGenericService implements GenericService {
public Object $invoke(String methodName, String[] parameterTypes, Object[] args) throws GenericException {
if ("sayHello".equals(methodName)) {
return "Welcome " + args[0];
}
}
}]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[...
GenericService xxxService = new XxxGenericService(); // 用com.alibaba.dubbo.rpc.service.GenericService可以替代所有接口实现
ServiceConfig&lt;GenericService&gt; service = new ServiceConfig&lt;GenericService&gt;(); // 该实例很重量,里面封装了所有与注册中心,请缓存
service.setInterface("com.xxx.XxxService"); // 弱类型接口名
service.setVersion("1.0.0");
service.setRef(xxxService); // 指向一个通用服务实现
// 暴露及注册服务
service.export();]]></script>
</div></div>
<h3><a name="Examples-EchoTest"></a>Echo Test</h3>
<p>(<a href="Echo+Test.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Echo+Test" title="Echo Test">+</a>) (<a href="#Examples-EchoTest">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>回声测试用于检测服务是否可用,回声测试按照正常请求流程执行,能够测试整个调用是否通畅,可用于监控。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>所有服务自动实现EchoService接口,只需将任意服务引用强制转型为EchoService,即可使用。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="memberService" interface="com.xxx.MemberService" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[MemberService memberService = ctx.getBean("memberService"); // 远程服务引用
EchoService echoService = (EchoService) memberService; // 强制转型为EchoService
String status = echoService.$echo("OK"); // 回声测试可用性
assert(status.equals("OK"))]]></script>
</div></div>
<h3><a name="Examples-RpcContext"></a>Rpc Context</h3>
<p>(<a href="Rpc+Context.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Rpc+Context" title="Rpc Context">+</a>) (<a href="#Examples-RpcContext">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>上下文中存放的是当前调用过程中所需的环境信息。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>所有配置信息都将转换为URL的参数,参见《<a href="User+Guide.htm#UserGuide-ConfigurationReference" tppabs="http://10.20.160.198/wiki/display/dubbo/User+Guide#UserGuide-ConfigurationReference">配置项一览表</a>》中的“对应URL参数”一列。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>注意</b><br />RpcContext是一个ThreadLocal的临时状态记录器,当接收到RPC请求,或发起RPC请求时,RpcContext的状态都会变化。<br/>
比如:A调B,B再调C,则B机器上,在B调C之前,RpcContext记录的是A调B的信息,在B调C之后,RpcContext记录的是B调C的信息。</td></tr></table></div>
<h4><a name="Examples-%281%29%E6%9C%8D%E5%8A%A1%E6%B6%88%E8%B4%B9%E6%96%B9"></a>(1) 服务消费方</h4>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[xxxService.xxx(); // 远程调用
boolean isConsumerSide = RpcContext.getContext().isConsumerSide(); // 本端是否为消费端,这里会返回true
String serverIP = RpcContext.getContext().getRemoteHost(); // 获取最后一次调用的提供方IP地址
String application = RpcContext.getContext().getUrl().getParameter("application"); // 获取当前服务配置信息,所有配置信息都将转换为URL的参数
// ...
yyyService.yyy(); // 注意:每发起RPC调用,上下文状态会变化
// ...]]></script>
</div></div>
<h4><a name="Examples-%282%29%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E6%96%B9"></a>(2) 服务提供方</h4>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[public class XxxServiceImpl implements XxxService {
public void xxx() { // 服务方法实现
boolean isProviderSide = RpcContext.getContext().isProviderSide(); // 本端是否为提供端,这里会返回true
String clientIP = RpcContext.getContext().getRemoteHost(); // 获取调用方IP地址
String application = RpcContext.getContext().getUrl().getParameter("application"); // 获取当前服务配置信息,所有配置信息都将转换为URL的参数
// ...
yyyService.yyy(); // 注意:每发起RPC调用,上下文状态会变化
isProviderSide = RpcContext.getContext().isProviderSide(); // 此时本端变成消费端,这里会返回false
// ...
}
}]]></script>
</div></div>
<h3><a name="Examples-AttachmentParameter"></a>Attachment Parameter</h3>
<p>(<a href="Attachment+Parameter.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Attachment+Parameter" title="Attachment Parameter">+</a>) (<a href="#Examples-AttachmentParameter">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>注:path,group,version,dubbo,token,timeout几个key有特殊处理,请使用其它key值。</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="context.png-version=1&modificationDate=1320941797000.png" tppabs="http://10.20.160.198/wiki/download/attachments/6950004/context.png?version=1&modificationDate=1320941797000" style="border: 0px solid black" /></span></p>
<h4><a name="Examples-%281%29%E6%9C%8D%E5%8A%A1%E6%B6%88%E8%B4%B9%E6%96%B9"></a>(1) 服务消费方</h4>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[RpcContext.getContext().setAttachment("index", "1"); // 隐式传参,后面的远程调用都会隐式将这些参数发送到服务器端,用于框架集成,不建议常规业务使用
xxxService.xxx(); // 远程调用
// ...]]></script>
</div></div>
<p>【注】 setAttachment设置的KV,在完成下面一次远程调用会被清空。即多次远程调用要多次设置。</p>
<h4><a name="Examples-%282%29%E6%9C%8D%E5%8A%A1%E6%8F%90%E4%BE%9B%E6%96%B9"></a>(2) 服务提供方</h4>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[public class XxxServiceImpl implements XxxService {
public void xxx() { // 服务方法实现
String index = RpcContext.getContext().getAttachment("index"); // 获取客户端隐式传入的参数,用于框架集成,不建议常规业务使用
// ...
}
}]]></script>
</div></div>
<h3><a name="Examples-AsyncCall"></a>Async Call</h3>
<p>(<a href="Async+Call.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Async+Call" title="Async Call">+</a>) (<a href="#Examples-AsyncCall">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>基于NIO的非阻塞实现并行调用,客户端不需要启动多线程即可完成并行调用多个远程服务,相对多线程开销较小。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.0.6及其以上版本支持</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="future.jpg-version=1&modificationDate=1320417743000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949442/future.jpg?version=1&modificationDate=1320417743000" style="border: 0px solid black" /></span></p>
<p><b>配置声明:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="fooService" interface="com.alibaba.foo.FooService"&gt;
&lt;dubbo:method name="findFoo" async="true" /&gt;
&lt;/dubbo:reference&gt;
&lt;dubbo:reference id="barService" interface="com.alibaba.bar.BarService"&gt;
&lt;dubbo:method name="findBar" async="true" /&gt;
&lt;/dubbo:reference&gt;]]></script>
</div></div>
<p><b>调用代码:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[fooService.findFoo(fooId); // 此调用会立即返回null
Future&lt;Foo&gt; fooFuture = RpcContext.getContext().getFuture(); // 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。
barService.findBar(barId); // 此调用会立即返回null
Future&lt;Bar&gt; barFuture = RpcContext.getContext().getFuture(); // 拿到调用的Future引用,当结果返回后,会被通知和设置到此Future。
// 此时findFoo和findBar的请求同时在执行,客户端不需要启动多线程来支持并行,而是借助NIO的非阻塞完成。
Foo foo = fooFuture.get(); // 如果foo已返回,直接拿到返回值,否则线程wait住,等待foo返回后,线程会被notify唤醒。
Bar bar = barFuture.get(); // 同理等待bar返回。
// 如果foo需要5秒返回,bar需要6秒返回,实际只需等6秒,即可获取到foo和bar,进行接下来的处理。]]></script>
</div></div>
<p>你也可以设置是否等待消息发出:(异步总是不等待返回)</p>
<ul>
<li>sent="true" 等待消息发出,消息发送失败将抛出异常。</li>
<li>sent="false" 不等待消息发出,将消息放入IO队列,即刻返回。
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:method name="findFoo" async="true" sent="true" /&gt;]]></script>
</div></div></li>
</ul>
<p>如果你只是想异步,完全忽略返回值,可以配置return="false",以减少Future对象的创建和管理成本:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:method name="findFoo" async="true" return="false" /&gt;]]></script>
</div></div>
<h3><a name="Examples-LocalCall"></a>Local Call</h3>
<p>(<a href="Local+Call.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Local+Call" title="Local Call">+</a>) (<a href="#Examples-LocalCall">&#35;</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>本地调用,使用了Injvm协议,是一个伪协议,它不开启端口,不发起远程调用,只在JVM内直接关联,但执行Dubbo的Filter链。</td></tr></table></div>
<p>Define injvm protocol:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="injvm" /&gt;]]></script>
</div></div>
<p>Set default protocol:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:provider protocol="injvm" /&gt;]]></script>
</div></div>
<p>Set service protocol:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service protocol="injvm" /&gt;]]></script>
</div></div>
<p>Use injvm first:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:consumer injvm="true" .../&gt;
&lt;dubbo:provider injvm="true" .../&gt;]]></script>
</div></div>
<p></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference injvm="true" .../&gt;
&lt;dubbo:service injvm="true" .../&gt;]]></script>
</div></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>注意:服务暴露与服务引用都需要声明injvm="true"</td></tr></table></div>
<h3><a name="Examples-ParameterCallback"></a>Parameter Callback</h3>
<p>(<a href="Parameter+Callback.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Parameter+Callback" title="Parameter Callback">+</a>) (<a href="#Examples-ParameterCallback">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>参数回调方式与调用本地callback或listener相同,只需要在Spring的配置文件中声明哪个参数是callback类型即可,Dubbo将基于长连接生成反向代理,这样就可以从服务器端调用客户端逻辑。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.0.6及其以上版本支持</td></tr></table></div>
<p>代码参见:<a href="javascript:if(confirm(%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback%27" tppabs="http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback" class="external-link" rel="nofollow">http://code.alibabatech.com/svn/dubbo/trunk/dubbo-test/dubbo-test-examples/src/main/java/com/alibaba/dubbo/examples/callback</a></p>
<p><b>(1) 共享服务接口:</b></p>
<p>服务接口示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>CallbackService.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.callback;
public interface CallbackService {
void addListener(String key, CallbackListener listener);
}]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>CallbackListener.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.callback;
public interface CallbackListener {
void changed(String msg);
}]]></script>
</div></div>
<p><b>(2) 服务提供者:</b></p>
<p>服务提供者接口实现示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>CallbackServiceImpl.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.callback.impl;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import com.callback.CallbackListener;
import com.callback.CallbackService;
public class CallbackServiceImpl implements CallbackService {
private final Map&lt;String, CallbackListener&gt; listeners = new ConcurrentHashMap&lt;String, CallbackListener&gt;();
public CallbackServiceImpl() {
Thread t = new Thread(new Runnable() {
public void run() {
while(true) {
try {
for(Map.Entry&lt;String, CallbackListener&gt; entry : listeners.entrySet()){
try {
entry.getValue().changed(getChanged(entry.getKey()));
} catch (Throwable t) {
listeners.remove(entry.getKey());
}
}
Thread.sleep(5000); // 定时触发变更通知
} catch (Throwable t) { // 防御容错
t.printStackTrace();
}
}
}
});
t.setDaemon(true);
t.start();
}
public void addListener(String key, CallbackListener listener) {
listeners.put(key, listener);
listener.changed(getChanged(key)); // 发送变更通知
}
private String getChanged(String key) {
return "Changed: " + new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date());
}
}]]></script>
</div></div>
<p>服务提供者配置示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;bean id="callbackService" class="com.callback.impl.CallbackServiceImpl" /&gt;
&lt;dubbo:service interface="com.callback.CallbackService" ref="callbackService" connections="1" callbacks="1000"&gt;
&lt;dubbo:method name="addListener"&gt;
&lt;dubbo:argument index="1" callback="true" /&gt;
&lt;!--也可以通过指定类型的方式--&gt;
&lt;!--&lt;dubbo:argument type="com.demo.CallbackListener" callback="true" /&gt;--&gt;
&lt;/dubbo:method&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p><b>(2) 服务消费者:</b></p>
<p>服务消费者配置示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference id="callbackService" interface="com.callback.CallbackService" /&gt;]]></script>
</div></div>
<p>服务消费者调用示例:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>CallbackServiceTest.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[ClassPathXmlApplicationContext context = new ClassPathXmlApplicationContext("classpath:consumer.xml");
context.start();
CallbackService callbackService = (CallbackService) context.getBean("callbackService");
callbackService.addListener("http://10.20.160.198/wiki/display/dubbo/foo.bar", new CallbackListener(){
public void changed(String msg) {
System.out.println("callback1:" + msg);
}
});]]></script>
</div></div>
<h3><a name="Examples-EventNotify"></a>Event Notify</h3>
<p>(<a href="Event+Notify.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Event+Notify" title="Event Notify">+</a>) (<a href="#Examples-EventNotify">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>在调用之前,调用之后,出现异常时,会触发oninvoke, onreturn, onthrow三个事件,可以配置当事件发生时,通知哪个类的哪个方法。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>支持版本:2.0.7之后</td></tr></table></div>
<p><b>(1) 服务提供者与消费者共享服务接口:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>IDemoService.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[interface IDemoService {
public Person get(int id);
}]]></script>
</div></div>
<p><b>(2) 服务提供者实现:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>DemoServiceImpl.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[class NormalDemoService implements IDemoService {
public Person get(int id) {
return new Person(id, "charles`son", 4);
}
}]]></script>
</div></div>
<p><b>(3) 服务提供者配置:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>provider.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:application name="rpc-callback-demo" /&gt;
&lt;dubbo:registry address="http://10.20.160.198/wiki/display/dubbo/10.20.153.186" /&gt;
&lt;bean id="demoService" class="com.alibaba.dubbo.callback.implicit.NormalDemoService" /&gt;
&lt;dubbo:service interface="com.alibaba.dubbo.callback.implicit.IDemoService" ref="demoService" version="1.0.0" group="cn"/&gt;]]></script>
</div></div>
<p><b>(4) 服务消费者Callback接口及实现:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Nofify.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[interface Nofify {
public void onreturn(Person msg, Integer id);
public void onthrow(Throwable ex, Integer id);
}]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>NofifyImpl.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[class NofifyImpl implements Nofify {
public Map&lt;Integer, Person&gt; ret = new HashMap&lt;Integer, Person&gt;();
public Map&lt;Integer, Throwable&gt; errors = new HashMap&lt;Integer, Throwable&gt;();
public void onreturn(Person msg, Integer id) {
System.out.println("onreturn:" + msg);
ret.put(id, msg);
}
public void onthrow(Throwable ex, Integer id) {
errors.put(id, ex);
}
}]]></script>
</div></div>
<p><b>(5) 服务消费者Callback接口及实现:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>consumer.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;bean id ="demoCallback" class = "com.alibaba.dubbo.callback.implicit.NofifyImpl" /&gt;
&lt;dubbo:reference id="demoService" interface="com.alibaba.dubbo.callback.implicit.IDemoService" version="1.0.0" group="cn" &gt;
&lt;dubbo:method name="get" async="true" onreturn = "demoCallback.onreturn" onthrow="demoCallback.onthrow" /&gt;
&lt;/dubbo:reference&gt;]]></script>
</div></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>注:<br/>
callback与async功能正交分解:<br/>
async=true,表示结果是否马上返回.<br/>
onreturn 表示是否需要回调.
<p>组合情况:(async=false 默认)<br/>
异步回调模式:async=true onreturn="xxx"<br/>
同步回调模式:async=false onreturn="xxx"<br/>
异步无回调 :async=true<br/>
同步无回调 :async=false</p></td></tr></table></div>
<p><b>(6) TEST CASE:</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>Test.java</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[IDemoService demoService = (IDemoService) context.getBean("demoService");
NofifyImpl notify = (NofifyImpl) context.getBean("demoCallback");
int requestId = 2;
Person ret = demoService.get(requestId);
Assert.assertEquals(null, ret);
//for Test:只是用来说明callback正常被调用,业务具体实现自行决定.
for (int i = 0; i &lt; 10; i++) {
if (!notify.ret.containsKey(requestId)) {
Thread.sleep(200);
} else {
break;
}
}
Assert.assertEquals(requestId, notify.ret.get(requestId).getId());]]></script>
</div></div>
<h3><a name="Examples-StubProxy"></a>Stub Proxy</h3>
<p>(<a href="Stub+Proxy.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Stub+Proxy" title="Stub Proxy">+</a>) (<a href="#Examples-StubProxy">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>远程服务后,客户端通常只剩下接口,而实现全在服务器端,但提供方有些时候想在客户端也执行部分逻辑,比如:做ThreadLocal缓存,提前验证参数,调用失败后伪造容错数据等等,此时就需要在API中带上Stub,客户端生成Proxy实,会把Proxy通过构造函数传给Stub,然后把Stub暴露组给用户,Stub可以决定要不要去调Proxy。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Stub必须有可传入Proxy的构造函数。</td></tr></table></div>
<p><span class="image-wrap" style=""><img src="stub.jpg-version=1&modificationDate=1320417778000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6949448/stub.jpg?version=1&modificationDate=1320417778000" style="border: 0px solid black" /></span></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" stub="true" /&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" stub="com.foo.BarServiceStub" /&gt;]]></script>
</div></div>
<p>api.jar:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: text; gutter: false"><![CDATA[com.foo.BarService
com.foo.BarServiceStub // 在API旁边放一个Stub实现,它实现BarService接口,并有一个传入远程BarService实例的构造函数]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.foo
public class BarServiceStub implements BarService {
private final BarService barService;
// 构造函数传入真正的远程代理对象
public (BarService barService) {
this.barService = barService;
}
public String sayHello(String name) {
// 此代码在客户端执行
// 你可以在客户端做ThreadLocal本地缓存,或预先验证参数是否合法,等等
try {
return barService.sayHello(name);
} catch (Exception e) {
// 你可以容错,可以做任何AOP拦截事项
return "容错数据";
}
}
}]]></script>
</div></div>
<h3><a name="Examples-MockProxy"></a>Mock Proxy</h3>
<p>(<a href="Mock+Proxy.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Mock+Proxy" title="Mock Proxy">+</a>) (<a href="#Examples-MockProxy">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Mock通常用于服务降级,比如某验权服务,当服务提供方全部挂掉后,客户端不抛出异常,而是通过Mock数据返回授权失败。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Mock是Stub的一个子集,便于服务提供方在客户端执行容错逻辑,因经常需要在出现RpcException(比如网络失败,超时等)时进行容错,而在出现业务异常(比如登录用户名密码错误)时不需要容错,如果用Stub,可能就需要捕获并依赖RpcException类,而用Mock就可以不依赖RpcException,因为它的约定就是只有出现RpcException时才执行。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" mock="true" /&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" mock="com.foo.BarServiceMock" /&gt;]]></script>
</div></div>
<p>api.jar:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: text; gutter: false"><![CDATA[com.foo.BarService
com.foo.BarServiceMock // 在API旁边放一个Mock实现,它实现BarService接口,并有一个无参构造函数]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[package com.foo
public class BarServiceMock implements BarService {
public String sayHello(String name) {
// 你可以伪造容错数据,此方法只在出现RpcException时被执行
return "容错数据";
}
}]]></script>
</div></div>
<p>如果服务的消费方经常需要try-catch捕获异常,如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[Offer offer = null;
try {
offer = offerService.findOffer(offerId);
} catch (RpcException e) {
logger.error(e);
}]]></script>
</div></div>
<p>请考虑改为Mock实现,并在Mock中return null。</p>
<p>如果只是想简单的忽略异常,在2.0.11以上版本可用:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" mock="return null" /&gt;]]></script>
</div></div>
<h3><a name="Examples-DelayExport"></a>Delay Export</h3>
<p>(<a href="Delay+Export.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Delay+Export" title="Delay Export">+</a>) (<a href="#Examples-DelayExport">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>如果你的服务需要Warmup时间,比如初始化缓存,等待相关资源就位等,可以使用delay进行延迟暴露。</td></tr></table></div>
<p>延迟5秒暴露服务:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service delay="5000" /&gt;]]></script>
</div></div>
<p>延迟到Spring初始化完成后,再暴露服务:(基于Spring的ContextRefreshedEvent事件触发暴露)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service delay="-1" /&gt;]]></script>
</div></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>Spring2.x初始化死锁问题</b><br />在Spring解析到&lt;dubbo:service /&gt;时,就已经向外暴露了服务,而Spring还在接着初始化其它Bean。<br/>
如果这时有请求进来,并且服务的实现类里有调用applicationContext.getBean()的用法。
<p>1. 请求线程的applicationContext.getBean()调用,先同步singletonObjects判断Bean是否存在,不存在就同步beanDefinitionMap进行初始化,并再次同步singletonObjects写入Bean实例缓存。<br/>
<span class="image-wrap" style=""><img src="lock-get-bean.jpg-version=1&modificationDate=1330949876000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6950732/lock-get-bean.jpg?version=1&modificationDate=1330949876000" style="border: 0px solid black" /></span><br/>
2. 而Spring初始化线程,因不需要判断Bean的存在,直接同步beanDefinitionMap进行初始化,并同步singletonObjects写入Bean实例缓存。<br/>
<span class="image-wrap" style=""><img src="lock-init-context.jpg-version=1&modificationDate=1330949881000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6950732/lock-init-context.jpg?version=1&modificationDate=1330949881000" style="border: 0px solid black" /></span></p>
<p>这样就导致getBean线程,先锁singletonObjects,再锁beanDefinitionMap,再次锁singletonObjects。<br/>
而Spring初始化线程,先锁beanDefinitionMap,再锁singletonObjects。<br/>
反向锁导致线程死锁,不能提供服务,启动不了。</p></td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td><b>规避办法</b><br />1. 强烈建议不要在服务的实现类中有applicationContext.getBean()的调用,全部采用IoC注入的方式使用Spring的Bean。<br/>
2. 如果实在要调getBean(),可以将Dubbo的配置放在Spring的最后加载。<br/>
3. 如果不想依赖配置顺序,可以使用&lt;dubbo:provider deplay=”-1” /&gt;,使Dubbo在Spring容器初始化完后,再暴露服务。<br/>
4. 如果大量使用getBean(),相当于已经把Spring退化为工厂模式在用,可以将Dubbo的服务隔离单独的Spring容器。</td></tr></table></div>
<h3><a name="Examples-ConcurrentControl"></a>Concurrent Control</h3>
<p>(<a href="Concurrent+Control.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Concurrent+Control" title="Concurrent Control">+</a>) (<a href="#Examples-ConcurrentControl">#</a>)</p>
<p>限制com.foo.BarService的每个方法,<b>服务器端</b>并发执行(或占用线程池线程数)不能超过10个:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" executes="10" /&gt;]]></script>
</div></div>
<p>限制com.foo.BarService的sayHello方法,<b>服务器端</b>并发执行(或占用线程池线程数)不能超过10个:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService"&gt;
&lt;dubbo:method name="sayHello" executes="10" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>限制com.foo.BarService的每个方法,每<b>客户端</b>并发执行(或占用连接的请求数)不能超过10个:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" actives="10" /&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" actives="10" /&gt;]]></script>
</div></div>
<p>限制com.foo.BarService的sayHello方法,每<b>客户端</b>并发执行(或占用连接的请求数)不能超过10个:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService"&gt;
&lt;dubbo:method name="sayHello" actives="10" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService"&gt;
&lt;dubbo:method name="sayHello" actives="10" /&gt;
&lt;/dubbo:service&gt;]]></script>
</div></div>
<p>如果&lt;dubbo:service&gt;和&lt;dubbo:reference&gt;都配了actives,&lt;dubbo:reference&gt;优先,参见:<a href="Configuration+Reference.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Configuration+Reference" title="Configuration Reference">配置的覆盖策略</a></p>
<p>Load Balance均衡:</p>
<p>配置服务的<b>客户端</b>的loadbalance属性为leastactive,此Loadbalance会调用并发数最小的Provider(Consumer端并发数)。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" loadbalance="leastactive" /&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" loadbalance="leastactive" /&gt;]]></script>
</div></div>
<h3><a name="Examples-ConnectionControl"></a>Connection Control</h3>
<p>(<a href="Connection+Control.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Connection+Control" title="Connection Control">+</a>) (<a href="#Examples-ConnectionControl">#</a>)</p>
<p>限制<b>服务器端</b>接受的连接不能超过10个:(以连接在Server上,所以配置在Provider上)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:provider protocol="dubbo" accepts="10" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="dubbo" accepts="10" /&gt;]]></script>
</div></div>
<p>限制<b>客户端服务</b>使用连接连接数:(如果是长连接,比如Dubbo协议,connections表示该服务对每个提供者建立的长连接数)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:reference interface="com.foo.BarService" connections="10" /&gt;]]></script>
</div></div>
<p>Or:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:service interface="com.foo.BarService" connections="10" /&gt;]]></script>
</div></div>
<p>如果&lt;dubbo:service&gt;和&lt;dubbo:reference&gt;都配了connections,&lt;dubbo:reference&gt;优先,参见:<a href="Configuration+Reference.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Configuration+Reference" title="Configuration Reference">配置的覆盖策略</a></p>
<h3><a name="Examples-LazyConnection"></a>Lazy Connection</h3>
<p>(<a href="Lazy+Connection.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Lazy+Connection" title="Lazy Connection">+</a>) (<a href="#Examples-LazyConnection">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>延迟连接,用于减少长连接数,当有调用发起时,再创建长连接。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>只对使用长连接的dubbo协议生效。</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="dubbo" lazy="true" /&gt;]]></script>
</div></div>
<h3><a name="Examples-StickyConnection"></a>Sticky Connection</h3>
<p>(<a href="Sticky+Connection.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Sticky+Connection" title="Sticky Connection">+</a>) (<a href="#Examples-StickyConnection">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>粘滞连接用于有状态服务,尽可能让客户端总是向同一提供者发起调用,除非该提供者挂了,再连另一台。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>粘滞连接将自动开启延迟连接,以减少长连接数,参见:<a href="#Examples-LazyConnection">Lazy Connection</a> (<a href="Lazy+Connection.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Lazy+Connection" title="Lazy Connection">+</a>)</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="dubbo" sticky="true" /&gt;]]></script>
</div></div>
<h3><a name="Examples-TokenVerify"></a>Token Verify</h3>
<p>(<a href="Token+Verify.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Token+Verify" title="Token Verify">+</a>) (<a href="#Examples-TokenVerify">#</a>)</p>
<p><span class="image-wrap" style=""><img src="dubbo-token.jpg-version=1&modificationDate=1326472608000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6950705/dubbo-token.jpg?version=1&modificationDate=1326472608000" style="border: 0px solid black" /></span></p>
<ul>
<li>防止消费者绕过注册中心访问提供者</li>
<li>在注册中心控制权限,以决定要不要下发令牌给消费者</li>
<li>注册中心可灵活改变授权方式,而不需修改或升级提供者</li>
</ul>
<p>可以全局设置开启令牌验证:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--随机token令牌,使用UUID生成--&gt;
&lt;dubbo:provider interface="com.foo.BarService" token="true" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--固定token令牌,相当于密码--&gt;
&lt;dubbo:provider interface="com.foo.BarService" token="123456" /&gt;]]></script>
</div></div>
<p>也可在服务级别设置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--随机token令牌,使用UUID生成--&gt;
&lt;dubbo:service interface="com.foo.BarService" token="true" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--固定token令牌,相当于密码--&gt;
&lt;dubbo:service interface="com.foo.BarService" token="123456" /&gt;]]></script>
</div></div>
<p>还可在协议级别设置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--随机token令牌,使用UUID生成--&gt;
&lt;dubbo:protocol name="dubbo" token="true" /&gt;]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;!--固定token令牌,相当于密码--&gt;
&lt;dubbo:protocol name="dubbo" token="123456" /&gt;]]></script>
</div></div>
<h3><a name="Examples-RouterRule"></a>Router Rule</h3>
<p>(<a href="Router+Rule.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Router+Rule" title="Router Rule">+</a>) (<a href="#Examples-RouterRule">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.2.0以上版本支持</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>路由规则扩展点:<a href="Developer+Guide.htm#DeveloperGuide-RouterFactorySPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-RouterFactorySPI">Router Factory SPI</a></td></tr></table></div>
<p>向注册中心写入路由规则:(通常由监控中心或治理中心的页面完成)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("condition://0.0.0.0/com.foo.BarService?category=routers&amp;dynamic=false&amp;rule=" + URL.encode("http://10.20.160.198/wiki/display/dubbo/host = 10.20.153.10 => host = 10.20.153.11") + "));]]></script>
</div></div>
<p>其中:</p>
<ul>
<li>condition://
<ul>
<li>表示路由规则的类型,支持<a href="#Examples-ConditionRouterRule">Condition Router Rule</a><a href="#Examples-ScriptRouterRule">Script Router Rule</a>,可扩展,必填。</li>
</ul>
</li>
<li>0.0.0.0
<ul>
<li>表示对所有IP地址生效,如果只想对某个IP的生效,请填入具体IP,必填。</li>
</ul>
</li>
<li>com.foo.BarService
<ul>
<li>表示只对指定服务生效,必填。</li>
</ul>
</li>
<li>category=routers
<ul>
<li>表示该数据为动态配置类型,必填。</li>
</ul>
</li>
<li>dynamic=false
<ul>
<li>表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,必填。</li>
</ul>
</li>
<li>enabled=true
<ul>
<li>覆盖规则是否生效,可不填,缺省生效。</li>
</ul>
</li>
<li>force=false
<ul>
<li>当路由结果为空时,是否强制执行,如果不强制执行,路由结果为空的路由规则将自动失效,可不填,缺省为flase。</li>
</ul>
</li>
<li>runtime=false
<ul>
<li>是否在每次调用时执行路由规则,否则只在提供者地址列表变更时预先执行并缓存结果,调用时直接从缓存中获取路由结果。</li>
<li>如果用了参数路由,必须设为true,需要注意设置会影响调用的性能,可不填,缺省为flase。</li>
</ul>
</li>
<li>priority=1
<ul>
<li>路由规则的优先级,用于排序,优先级越大越靠前执行,可不填,缺省为0。</li>
</ul>
</li>
<li>rule=URL.encode("host = 10.20.153.10 =&gt; host = 10.20.153.11")
<ul>
<li>表示路由规则的内容,必填。</li>
</ul>
</li>
</ul>
<h4><a name="Examples-ConditionRouterRule"></a>Condition Router Rule</h4>
<p>(<a href="#Examples-ConditionRouterRule">#</a>)</p>
<p>基于条件表达式的路由规则,如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[host = 10.20.153.10 =&gt; host = 10.20.153.11]]></script>
</div></div>
<p>规则:</p>
<ul>
<li>"=&gt;"之前的为消费者匹配条件,所有参数和消费者的URL进行对比,当消费者满足匹配条件时,对该消费者执行后面的过滤规则。</li>
<li>"=&gt;"之后为提供者地址列表的过滤条件,所有参数和提供者的URL进行对比,消费者最终只拿到过滤后的地址列表。</li>
<li>如果匹配条件为空,表示对所有消费方应用,如:=&gt; host != 10.20.153.11</li>
<li>如果过滤条件为空,表示禁止访问,如:host = 10.20.153.10 =&gt;</li>
</ul>
<p>表达式:</p>
<ul>
<li>参数支持:
<ul>
<li>服务调用信息,如:method, <del>argument</del><del>(暂不支持参数路由)</del></li>
<li>URL本身的字段,如:protocol, host, port 等</li>
<li>以及URL上的所有参数,如:application, organization 等</li>
</ul>
</li>
<li>条件支持:
<ul>
<li>等号"="表示"匹配",如:host = 10.20.153.10</li>
<li>不等号"!="表示"不匹配",如:host != 10.20.153.10</li>
</ul>
</li>
<li>值支持:
<ul>
<li>以逗号","分隔多个值,如:host != 10.20.153.10,10.20.153.11</li>
<li>以星号"&#42;"结尾,表示通配,如:host != 10.20.*</li>
<li>以美元符"$"开头,表示引用消费者参数,如:host = $host</li>
</ul>
</li>
</ul>
<p>示例:</p>
<p>1. 排除预发布机:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[=&gt; host != 172.22.3.91]]></script>
</div></div>
<p>2. 白名单:(注意:一个服务只能有一条白名单规则,否则两条规则交叉,就都被筛选掉了)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[host != 10.20.153.10,10.20.153.11 =&gt;]]></script>
</div></div>
<p>3. 黑名单:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[host = 10.20.153.10,10.20.153.11 =&gt;]]></script>
</div></div>
<p>4. 服务寄宿在应用上,只暴露一部分的机器,防止整个集群挂掉:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[=&gt; host = 172.22.3.1*,172.22.3.2*]]></script>
</div></div>
<p>5. 为重要应用提供额外的机器:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[application != kylin =&gt; host != 172.22.3.95,172.22.3.96]]></script>
</div></div>
<p>6. 读写分离:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[method = find*,list*,get*,is* =&gt; host = 172.22.3.94,172.22.3.95,172.22.3.96]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[method != find*,list*,get*,is* =&gt; host = 172.22.3.97,172.22.3.98]]></script>
</div></div>
<p>7. 前后台分离:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[application = bops =&gt; host = 172.22.3.91,172.22.3.92,172.22.3.93]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[application != bops =&gt; host = 172.22.3.94,172.22.3.95,172.22.3.96]]></script>
</div></div>
<p>8. 隔离不同机房网段:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[host != 172.22.3.* =&gt; host != 172.22.3.*]]></script>
</div></div>
<p>9. 提供者与消费者部署在同集群内,本机只访问本机的服务:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[=&gt; host = $host]]></script>
</div></div>
<h4><a name="Examples-ScriptRouterRule"></a>Script Router Rule</h4>
<p>(<a href="#Examples-ScriptRouterRule">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>支持<a href="javascript:if(confirm(%27http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting%27" tppabs="http://java.sun.com/developer/technicalArticles/J2SE/Desktop/scripting" class="external-link" rel="nofollow">JDK脚本引擎</a>的所有脚本,比如:javascript,jruby,groovy等,通过type=javascript参数设置脚本类型,缺省为javascript。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>脚本没有沙箱约束,可执行任意代码,存在后门风险</td></tr></table></div>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA["script://0.0.0.0/com.foo.BarService?category=routers&amp;dynamic=false&amp;rule=" + URL.encode("function route(invokers) { ... } (invokers)")]]></script>
</div></div>
<p>基于脚本引擎的路由规则,如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: javascript; gutter: false"><![CDATA[function route(invokers) {
var result = new java.util.ArrayList(invokers.size());
for (i = 0; i &lt; invokers.size(); i ++) {
if ("http://10.20.160.198/wiki/display/dubbo/10.20.153.10".equals(invokers.get(i).getUrl().getHost())) {
result.add(invokers.get(i));
}
}
return result;
} (invokers); // 表示立即执行方法]]></script>
</div></div>
<h3><a name="Examples-ConfiguratorRule"></a>Configurator Rule</h3>
<p>(<a href="Configurator+Rule.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Configurator+Rule" title="Configurator Rule">+</a>) (<a href="#Examples-ConfiguratorRule">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.2.0以上版本支持</td></tr></table></div>
<p>向注册中心写入动态配置覆盖规则:(通常由监控中心或治理中心的页面完成)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&amp;dynamic=false&amp;application=foo&amp;timeout=1000"));]]></script>
</div></div>
<p>其中:</p>
<ul>
<li>override://
<ul>
<li>表示数据采用覆盖方式,支持override和absent,可扩展,必填。</li>
</ul>
</li>
<li>0.0.0.0
<ul>
<li>表示对所有IP地址生效,如果只想覆盖某个IP的数据,请填入具体IP,必填。</li>
</ul>
</li>
<li>com.foo.BarService
<ul>
<li>表示只对指定服务生效,必填。</li>
</ul>
</li>
<li>category=configurators
<ul>
<li>表示该数据为动态配置类型,必填。</li>
</ul>
</li>
<li>dynamic=false
<ul>
<li>表示该数据为持久数据,当注册方退出时,数据依然保存在注册中心,必填。</li>
</ul>
</li>
<li>enabled=true
<ul>
<li>覆盖规则是否生效,可不填,缺省生效。</li>
</ul>
</li>
<li>application=foo
<ul>
<li>表示只对指定应用生效,可不填,表示对所有应用生效。</li>
</ul>
</li>
<li>timeout=1000
<ul>
<li>表示将满足以上条件的timeout参数的值覆盖为1000。</li>
<li>如果想覆盖其它参数,直接加在override的URL参数上。</li>
</ul>
</li>
</ul>
<p>示例:</p>
<p>1. 禁用提供者:(通常用于临时踢除某台提供者机器,相似的,禁止消费者访问请使用<a href="User+Guide.htm#UserGuide-RouterRule" tppabs="http://10.20.160.198/wiki/display/dubbo/User+Guide#UserGuide-RouterRule">路由规则</a>)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[override://10.20.153.10/com.foo.BarService?category=configurators&amp;dynamic=false&amp;disbaled=true]]></script>
</div></div>
<p>2. 调整权重:(通常用于容量评估,缺省权重为100)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[override://10.20.153.10/com.foo.BarService?category=configurators&amp;dynamic=false&amp;weight=200]]></script>
</div></div>
<p>3. 调整负载均衡策略:(缺省负载均衡策略为random)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[override://10.20.153.10/com.foo.BarService?category=configurators&amp;dynamic=false&amp;loadbalance=leastactive]]></script>
</div></div>
<p>4. 服务降级:(通常用于临时屏蔽某个出错的非关键服务)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[override://0.0.0.0/com.foo.BarService?category=configurators&amp;dynamic=false&amp;application=foo&amp;mock=force:return+null]]></script>
</div></div>
<h3><a name="Examples-ServiceDegradation"></a>Service Degradation</h3>
<p>(<a href="Service+Degradation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Service+Degradation" title="Service Degradation">+</a>) (<a href="#Examples-ServiceDegradation">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.2.0以上版本支持</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>参见:<a href="#Examples-ConfiguratorRule">Configurator Rule</a></td></tr></table></div>
<p>向注册中心写入动态配置覆盖规则:(通过由监控中心或治理中心的页面完成)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[RegistryFactory registryFactory = ExtensionLoader.getExtensionLoader(RegistryFactory.class).getAdaptiveExtension();
Registry registry = registryFactory.getRegistry(URL.valueOf("zookeeper://10.20.153.10:2181"));
registry.register(URL.valueOf("override://0.0.0.0/com.foo.BarService?category=configurators&amp;dynamic=false&amp;application=foo&amp;mock=force:return+null"));]]></script>
</div></div>
<p>其中:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[mock=force:return+null]]></script>
</div></div>
<ul>
<li>表示消费方对该服务的方法调用都直接返回null值,不发起远程调用。</li>
<li>屏蔽不重要服务不可用时对调用方的影响。</li>
</ul>
<p>还可以改为:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[mock=fail:return+null]]></script>
</div></div>
<ul>
<li>表示消费方对该服务的方法调用在失败后,再返回null值,不抛异常。</li>
<li>容忍不重要服务不稳定时对调用方的影响。</li>
</ul>
<h3><a name="Examples-GracefulShutdown"></a>Graceful Shutdown</h3>
<p>(<a href="Graceful+Shutdown.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Graceful+Shutdown" title="Graceful Shutdown">+</a>) (<a href="#Examples-GracefulShutdown">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>Dubbo是通过JDK的ShutdownHook来完成优雅停机的,所以如果用户使用"kill -9 PID"等强制关闭指令,是不会执行优雅停机的,只有通过"kill PID"时,才会执行。</td></tr></table></div>
<p>原理:</p>
<ul>
<li>服务提供方
<ul>
<li>停止时,先标记为不接收新请求,新请求过来时直接报错,让客户端重试其它机器。</li>
<li>然后,检测线程池中的线程是否正在运行,如果有,等待所有线程执行完成,除非超时,则强制关闭。</li>
</ul>
</li>
<li>服务消费方
<ul>
<li>停止时,不再发起新的调用请求,所有新的调用在客户端即报错。</li>
<li>然后,检测有没有请求的响应还没有返回,等待响应返回,除非超时,则强制关闭。</li>
</ul>
</li>
</ul>
<p>设置优雅停机超时时间,缺省超时时间是<font color="brown">10秒</font>:(超时则强制关闭)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:application ...&gt;
&lt;dubbo:parameter key="shutdown.timeout" value="60000" /&gt; &lt;!-- 单位毫秒 --&gt;
&lt;/dubbo:application&gt;]]></script>
</div></div>
<p>如果ShutdownHook不能生效,可以自行调用:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[ProtocolConfig.destroyAll();]]></script>
</div></div>
<h3><a name="Examples-HostBinding"></a>Host Binding</h3>
<p>(<a href="Host+Binding.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Host+Binding" title="Host Binding">+</a>) (<a href="#Examples-HostBinding">#</a>)</p>
<p>缺省主机IP查找顺序:</p>
<ul>
<li>通过LocalHost.getLocalHost()获取本机地址。</li>
<li>如果是127.*等loopback地址,则扫描各网卡,获取网卡IP。</li>
</ul>
<p>注册的地址如果获取不正确,比如需要注册公网地址,可以:<br/>
1. 可以在/etc/hosts中加入:机器名 公网IP,比如:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[test1 205.182.23.201]]></script>
</div></div>
<p>2. 在dubbo.xml中加入主机地址的配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol host="http://10.20.160.198/wiki/display/dubbo/205.182.23.201"&gt;]]></script>
</div></div>
<p>3. 或在dubbo.properties中加入主机地址的配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[dubbo.protocol.host=205.182.23.201]]></script>
</div></div>
<p>缺省主机端口与协议相关:</p>
<ul>
<li>dubbo: 20880</li>
<li>rmi: 1099</li>
<li>http: 80</li>
<li>hessian: 80</li>
<li>webservice: 80</li>
<li>memcached: 11211</li>
<li>redis: 6379</li>
</ul>
<p>主机端口配置:</p>
<p>1. 在dubbo.xml中加入主机地址的配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol name="dubbo" port="20880"&gt;]]></script>
</div></div>
<p>3. 或在dubbo.properties中加入主机地址的配置:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[dubbo.protocol.dubbo.port=20880]]></script>
</div></div>
<h3><a name="Examples-LoggerAdpater"></a>Logger Adpater</h3>
<p>(<a href="Logger+Adpater.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Logger+Adpater" title="Logger Adpater">+</a>) (<a href="#Examples-LoggerAdpater">#</a>)</p>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>2.2.1以上版本支持</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>扩展点:<a href="Developer+Guide.htm#DeveloperGuide-LoggerAdapterSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-LoggerAdapterSPI">日志适配扩展</a></td></tr></table></div>
<p>缺省自动查找:</p>
<ul>
<li>log4j</li>
<li>slf4j</li>
<li>jcl</li>
<li>jdk</li>
</ul>
<p>可以通过以下方式配置日志输出策略:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java -Ddubbo.application.logger=log4j]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dubbo.properties</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[dubbo.application.logger=log4j]]></script>
</div></div>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dubbo.xml</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[&lt;dubbo:application logger="log4j" /&gt;]]></script>
</div></div>
<h3><a name="Examples-AccessLog"></a>Access Log</h3>
<p>(<a href="Access+Log.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Access+Log" title="Access Log">+</a>) (<a href="#Examples-AccessLog">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>如果你想记录每一次请求信息,可开启访问日志,类似于apache的访问日志。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>此日志量比较大,请注意磁盘容量。</td></tr></table></div>
<p>将访问日志输出到当前应用的log4j日志:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol accesslog="true" /&gt;]]></script>
</div></div>
<p>将访问日志输出到指定文件:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;dubbo:protocol accesslog="http://10.20.160.198/wiki/display/dubbo/foo/bar.log" /&gt;]]></script>
</div></div>
<h3><a name="Examples-ServiceContainer"></a>Service Container</h3>
<p>(<a href="Service+Container.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Service+Container" title="Service Container">+</a>) (<a href="#Examples-ServiceContainer">&#35;</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>服务容器是一个standalone的启动程序,因为后台服务不需要Tomcat或JBoss等Web容器的功能,如果硬要用Web容器去加载服务提供方,增加复杂性,也浪费资源。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>服务容器只是一个简单的Main方法,并加载一个简单的Spring容器,用于暴露服务。</td></tr></table></div>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>服务容器的加载内容可以扩展,内置了spring, jetty, log4j等加载,可通过Container扩展点进行扩展,参见:<a href="Developer+Guide.htm#DeveloperGuide-ContainerSPI" tppabs="http://10.20.160.198/wiki/display/dubbo/Developer+Guide#DeveloperGuide-ContainerSPI">Container</a></td></tr></table></div>
<h6><a name="Examples-SpringContainer"></a>Spring Container</h6>
<ul>
<li>自动加载META-INF/spring目录下的所有Spring配置。</li>
<li>配置:(配在java命令-D参数或者dubbo.properties中)
<ul>
<li>dubbo.spring.config=classpath*:META-INF/spring/*.xml ----配置spring配置加载位置</li>
</ul>
</li>
</ul>
<h6><a name="Examples-JettyContainer"></a>Jetty Container</h6>
<ul>
<li>启动一个内嵌Jetty,用于汇报状态。</li>
<li>配置:(配在java命令-D参数或者dubbo.properties中)
<ul>
<li>dubbo.jetty.port=8080 ----配置jetty启动端口</li>
<li>dubbo.jetty.directory=/foo/bar ----配置可通过jetty直接访问的目录,用于存放静态文件</li>
<li>dubbo.jetty.page=log,status,system ----配置显示的页面,缺省加载所有页面</li>
</ul>
</li>
</ul>
<h6><a name="Examples-Log4jContainer"></a>Log4j Container</h6>
<ul>
<li>自动配置log4j的配置,在多进程启动时,自动给日志文件按进程分目录。</li>
<li>配置:(配在java命令-D参数或者dubbo.properties中)
<ul>
<li>dubbo.log4j.file=/foo/bar.log ----配置日志文件路径</li>
<li>dubbo.log4j.level=WARN ----配置日志级别</li>
<li>dubbo.log4j.subdirectory=20880 ----配置日志子目录,用于多进程启动,避免冲突</li>
</ul>
</li>
</ul>
<p><b>容器启动</b></p>
<p>如:(缺省只加载spring)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java com.alibaba.dubbo.container.Main]]></script>
</div></div>
<p>或:(通过main函数参数传入要加载的容器)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java com.alibaba.dubbo.container.Main spring jetty log4j]]></script>
</div></div>
<p>或:(通过JVM启动参数传入要加载的容器)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[java com.alibaba.dubbo.container.Main -Ddubbo.container=spring,jetty,log4j]]></script>
</div></div>
<p>或:(通过classpath下的dubbo.properties配置传入要加载的容器)</p>
<div class="code panel" style="border-width: 1px;"><div class="codeHeader panelHeader" style="border-bottom-width: 1px;"><b>dubbo.properties</b></div><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[dubbo.container=spring,jetty,log4j]]></script>
</div></div>
<p><b>在web容器中使用内置的监控页面</b></p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: xml; gutter: false"><![CDATA[&lt;filter&gt;
&lt;filter-name&gt;resource&lt;/filter-name&gt;
&lt;filter-class&gt;com.alibaba.dubbo.container.page.ResourceFilter&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;servlet&gt;
&lt;servlet-name&gt;page&lt;/servlet-name&gt;
&lt;servlet-class&gt;com.alibaba.dubbo.container.page.PageServlet&lt;/servlet-class&gt;
&lt;load-on-startup&gt;2&lt;/load-on-startup&gt;
&lt;/servlet&gt;
&lt;servlet-mapping&gt;
&lt;servlet-name&gt;page&lt;/servlet-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/servlet-mapping&gt;
&lt;filter-mapping&gt;
&lt;filter-name&gt;resource&lt;/filter-name&gt;
&lt;url-pattern&gt;/*&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;]]></script>
</div></div>
<h3><a name="Examples-ReferenceConfigCache"></a>Reference Config Cache</h3>
<p>(<a href="Reference+Config+Cache.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Reference+Config+Cache" title="Reference Config Cache">+</a>) (<a href="#Examples-ReferenceConfigCache">#</a>)</p>
<p>ReferenceConfig实例很重,封装了与注册中心的连接以及与提供者的连接,需要缓存,否则重复生成ReferenceConfig可能造成性能问题并且会有内存和连接泄漏。API方式编程时,容易忽略此问题。</p>
<p>Dubbo <font color="brown">2.4.0+</font>版本,提供了简单的工具类ReferenceConfigCache用于缓存ReferenceConfig实例。</p>
<p>使用方式如下:</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[ReferenceConfig&lt;XxxService&gt; reference = new ReferenceConfig&lt;XxxService&gt;();
reference.setInterface(XxxService.class);
reference.setVersion("1.0.0");
......
ReferenceConfigCache cache = ReferenceConfigCache.getCache();
XxxService xxxService = cache.get(reference); // cache.get方法中会Cache Reference对象,并且调用ReferenceConfig.get方法启动ReferenceConfig
// 注意! Cache会持有ReferenceConfig,不要在外部再调用ReferenceConfig的destroy方法,导致Cache内的ReferenceConfig失效!
// 使用xxxService对象
xxxService.sayHello();]]></script>
</div></div>
<p>消除Cache中的ReferenceConfig,销毁ReferenceConfig并释放对应的资源。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[ReferenceConfigCache cache = ReferenceConfigCache.getCache();
cache.destroy(reference);]]></script>
</div></div>
<p>缺省ReferenceConfigCache把相同服务Group、接口、版本的ReferenceConfig认为是相同,缓存一份。即以服务Group、接口、版本为缓存的Key。</p>
<p>可以修改这个策略,在ReferenceConfigCache.getCache时,传一个KeyGenerator。详见ReferenceConfigCache类的方法。</p>
<div class="code panel" style="border-width: 1px;"><div class="codeContent panelContent">
<script type="syntaxhighlighter" class="theme: Confluence; brush: java; gutter: false"><![CDATA[KeyGenerator keyGenerator = new ...
ReferenceConfigCache cache = ReferenceConfigCache.getCache(keyGenerator );]]></script>
</div></div>
<h3><a name="Examples-DistributedTransaction"></a>Distributed Transaction</h3>
<p>(<a href="Distributed+Transaction.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Distributed+Transaction" title="Distributed Transaction">+</a>) (<a href="#Examples-DistributedTransaction">#</a>)</p>
<div class='panelMacro'><table class='tipMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="check.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/check.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>基于JTA/XA规范实现。</td></tr></table></div>
<div class='panelMacro'><table class='noteMacro'><colgroup><col width='24'><col></colgroup><tr><td valign='top'><img src="warning-3.gif" tppabs="http://10.20.160.198/wiki/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle" alt="" border="0"></td><td>暂未实现。</td></tr></table></div>
<p>两阶段提交:</p>
<p><span class="image-wrap" style=""><img src="jta-xa.jpg-version=1&modificationDate=1333185059000.jpg" tppabs="http://10.20.160.198/wiki/download/attachments/6950008/jta-xa.jpg?version=1&modificationDate=1333185059000" style="border: 0px solid black" /></span></p>
</div>
<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://code.alibabatech.com/wiki/display/dubbo/Examples"
dc:identifier="http://code.alibabatech.com/wiki/display/dubbo/Examples"
dc:title="Examples"
trackback:ping="http://code.alibabatech.com/wiki/rpc/trackback/6947109"/>
</rdf:RDF>
-->
<fieldset class="hidden parameters">
<legend>Labels parameters</legend>
<input type="hidden" id="domainName" value="http://code.alibabatech.com/wiki">
<input type="hidden" id="pageId" value="6947109">
<input type="hidden" id="spaceKey" value="dubbo">
</fieldset>
<div id="labels-section" class="pageSection">
<div class="labels-editor">
<span id="labels-section-title" class="label-title">
<b>Labels:</b>
</span>
<div id="labels-section-content" class="content-column">
<span id="labels-section-title-none" class="label-title none hidden ">
None
</span>
<div id="labelsList" class="label-list">
<div id="label-7307267" class="confluence-label">
<a class="label" rel="nofollow" href="javascript:if(confirm(%27http://10.20.160.198/wiki/label/dubbo/dubbo \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/label/dubbo/dubbo%27" tppabs="http://10.20.160.198/wiki/label/dubbo/dubbo">dubbo</a> <span class="remove-label-caption">dubbo</span>
<a class="remove-label" href="#">Delete</a>
</div>
<div id="label-7307287" class="confluence-label">
<a class="label" rel="nofollow" href="javascript:if(confirm(%27http://10.20.160.198/wiki/label/dubbo/examples \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/label/dubbo/examples%27" tppabs="http://10.20.160.198/wiki/label/dubbo/examples">examples</a> <span class="remove-label-caption">examples</span>
<a class="remove-label" href="#">Delete</a>
</div>
</div>
</div>
<span class="errorMessage error" id="errorSpan"></span>
<form method="GET" action="" id="add-labels-form">
<div id="labelInputSpan" class="labels-input">
<div id="labelOperationErrorContainer" class="hidden">
<span class="error"><span class="errorMessage" id="labelOperationErrorMessage"></span></span>
</div>
<div class="caption">Enter labels to add to this page:</div>
<div id="label-input-fields">
<input autocomplete="off" id="labelsString" name="labelsString" value="" size="40">
<input id="add-labels-editor-button" type="submit" class="add-labels" value="Add">
<input id="close-labels-editor-button" type="submit" class="hide-labels-editor" value="Done">
</div>
<div id="waitImageAndStatus">
<img class="waiting" alt="Please wait" src="wait.gif" tppabs="http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/wait.gif">&nbsp;
<span id="labelOperationStatus" class="smalltext"></span>
</div>
<div id="labelsAutocompleteList" class="aui-dd-parent"></div>
<div class="labels-tip">
<div id="suggestedLabelsSpan"></div>
Looking for a label? Just start typing.
</div>
</div>
</form>
</div>
</div>
<div id="children-section" class="pageSection children-showing">
<div class="section-header ">
<h2 id="children-section-title" class="section-title">
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false \n\nThis file was not retrieved by Teleport Ultra, because it is linked too far away from its Starting Address. If you increase the in-domain depth setting for the Starting Address, this file will be queued for retrieval. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false#children%27" tppabs="http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false#children" class="children-show-hide">
44 Child Pages
</a>
</h2>
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false \n\nThis file was not retrieved by Teleport Ultra, because it is linked too far away from its Starting Address. If you increase the in-domain depth setting for the Starting Address, this file will be queued for retrieval. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false#children%27" tppabs="http://10.20.160.198/wiki/display/dubbo/Examples?showChildren=false#children" class="children-show-hide icon"></a>
<span class="noprint grey">
<a class="children-subtitle" href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109#selectedPageInHierarchy%27" tppabs="http://10.20.160.198/wiki/pages/listpages-dirview.action?key=dubbo&openId=6947109#selectedPageInHierarchy">Reorder Pages</a>
</span>
</div>
<div id="page-children" class="pageSectionBody children-loaded">
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Access+Log.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Access+Log">Access Log</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Async+Call.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Async+Call">Async Call</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Attachment+Parameter.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Attachment+Parameter">Attachment Parameter</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Check+On+Startup.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Check+On+Startup">Check On Startup</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Concurrent+Control.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Concurrent+Control">Concurrent Control</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Configurator+Rule.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Configurator+Rule">Configurator Rule</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Connection+Control.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Connection+Control">Connection Control</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Delay+Export.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Delay+Export">Delay Export</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo/Delay+Register \n\nThis file was not retrieved by Teleport Ultra, because it is linked too far away from its Starting Address. If you increase the in-domain depth setting for the Starting Address, this file will be queued for retrieval. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo/Delay+Register%27" tppabs="http://10.20.160.198/wiki/display/dubbo/Delay+Register">Delay Register</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Directly+Provider.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Directly+Provider">Directly Provider</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Distributed+Transaction.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Distributed+Transaction">Distributed Transaction</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Echo+Test.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Echo+Test">Echo Test</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Event+Notify.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Event+Notify">Event Notify</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Fault+Tolerance.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Fault+Tolerance">Fault Tolerance</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Generic+Implementation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Generic+Implementation">Generic Implementation</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Generic+Reference.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Generic+Reference">Generic Reference</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Graceful+Shutdown.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Graceful+Shutdown">Graceful Shutdown</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Host+Binding.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Host+Binding">Host Binding</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/display/dubbo/Http+Server \n\nThis file was not retrieved by Teleport Ultra, because it is linked too far away from its Starting Address. If you increase the in-domain depth setting for the Starting Address, this file will be queued for retrieval. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/display/dubbo/Http+Server%27" tppabs="http://10.20.160.198/wiki/display/dubbo/Http+Server">Http Server</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Lazy+Connection.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Lazy+Connection">Lazy Connection</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Load+Balance.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Load+Balance">Load Balance</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Local+Call.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Local+Call">Local Call</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Logger+Adpater.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Logger+Adpater">Logger Adpater</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Merge+By+Group.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Merge+By+Group">Merge By Group</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Mock+Proxy.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Mock+Proxy">Mock Proxy</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Multi+Group.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Group">Multi Group</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Multi+Protocol.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Protocol">Multi Protocol</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Multi+Registry.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Registry">Multi Registry</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Multi+Version.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Multi+Version">Multi Version</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Parameter+Callback.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Parameter+Callback">Parameter Callback</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Parameter+Validation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Parameter+Validation">Parameter Validation</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Reference+Config+Cache.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Reference+Config+Cache">Reference Config Cache</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Register+Only.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Register+Only">Register Only</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Result+Cache.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Result+Cache">Result Cache</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Router+Rule.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Router+Rule">Router Rule</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Rpc+Context.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Rpc+Context">Rpc Context</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Service+Container.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Service+Container">Service Container</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Service+Degradation.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Service+Degradation">Service Degradation</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Static+Provider.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Static+Provider">Static Provider</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Sticky+Connection.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Sticky+Connection">Sticky Connection</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Stub+Proxy.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Stub+Proxy">Stub Proxy</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Subscribe+Only.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Subscribe+Only">Subscribe Only</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Thread+Model.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Thread+Model">Thread Model</a>
</span>
<span class="child-display">
<span class="icon icon-page" title="Page">Page:</span>
<a href="Token+Verify.htm" tppabs="http://10.20.160.198/wiki/display/dubbo/Token+Verify">Token Verify</a>
</span>
</div>
</div>
<fieldset class="parameters hidden">
<input type="hidden" id="deleteCommentConfirmMessage" value="Are you sure you want to remove the comment?">
<input type="hidden" id="collapseTooltip" value="Click to toggle the display of this comment.">
</fieldset>
<fieldset class="hidden parameters i18n">
<input type="hidden" title="i18n.cancel.name" value="Cancel">
</fieldset>
<div id="comments-section" class="pageSection">
<div class="section-header ">
<h2 id="comments-section-title" class="section-title">
<a href="#" class="comments-show-hide comments-showing" name="comments">
1 Comment
</a>
</h2>
<a title="comments.show.hide" href="#"
class="comments-show-hide icon comments-showing icon-section-opened">
comments.show.hide
</a>
</div>
<ol class="comment-threads top-level " id="page-comments">
<li id="comment-thread-9338892" class="comment-thread">
<div class="comment " id="comment-9338892">
<p class="comment-user-logo">
<img class="userLogo logo anonymous" src="anonymous.png" tppabs="http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/profilepics/anonymous.png"
alt="User icon: Anonymous" title="Anonymous"> </p>
<p class="date" title="十二月 04, 2013 11:03">
十二月 04, 2013
</p>
<div class="comment-header">
<h4 class="author">Anonymous</h4>
</div>
<div class="comment-body">
<div class="comment-content wiki-content">
<p>为什么不能给个 集群搭建手册呢?纯新手完全不知道怎么下手</p>
</div>
<div class="comment-actions">
<ul id="comment-actions-secondary">
<li class="first comment-permalink">
<a title="Permanent link to this comment" href="Examples-focusedCommentId=9338892.htm#comment-9338892" tppabs="http://10.20.160.198/wiki/display/dubbo/Examples?focusedCommentId=9338892#comment-9338892"
id="comment-permalink-9338892" ><span>Permalink</span></a></li>
</ul>
<ul id="comment-actions-primary">
<li class="first action-reply-comment">
<a href="javascript:if(confirm(%27http://10.20.160.198/wiki/pages/replycomment.action?commentId=9338892&pageId=6947109 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/pages/replycomment.action?commentId=9338892&pageId=6947109%27" tppabs="http://10.20.160.198/wiki/pages/replycomment.action?commentId=9338892&pageId=6947109"
id="reply-comment-9338892" ><span>Reply</span></a></li>
</ul>
</div>
</div>
</div>
<!--
<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
xmlns:dc="http://purl.org/dc/elements/1.1/"
xmlns:trackback="http://madskills.com/public/xml/rss/module/trackback/">
<rdf:Description
rdf:about="http://code.alibabatech.com/wiki/display/dubbo/Examples?focusedCommentId=9338892#comment-9338892"
dc:identifier="http://code.alibabatech.com/wiki/display/dubbo/Examples?focusedCommentId=9338892#comment-9338892"
dc:title="Examples"
trackback:ping="http://code.alibabatech.com/wiki/rpc/trackback/9338892"/>
</rdf:RDF>
-->
</li>
</ol>
<div class="comment add" id="addcomment">
<p class="comment-user-logo">
<img class="userLogo logo anonymous" src="anonymous.png" tppabs="http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/profilepics/anonymous.png"
alt="User icon: Anonymous" title="Anonymous"> </p>
<div class="comment-header">
<h4 class="author">Anonymous replies:</h4>
</div>
<div id="addcomment-sidebar" class="sidebar">
<div id="info-panel" class="rightpanel">
<h3 id="helpheading">Help Tips</h3>
<div id="helpcontent">
<dl>
<dt class="first">Text formatting</dt>
<dd class="text-formatting"><code>*bold*</code> <strong>bold</strong></dd>
<dd class="text-formatting"><code>_italic_</code> <em>italic</em></dd>
<dt>Headings
<dd><code>h1.</code> Large heading</dd>
<dd><code>h5.</code> Small heading</dd>
<dt>Lists</dt>
<dd><code>*</code> Bulleted point</dd>
<dd><code>#</code> Numbered point</dd>
</dl>
<a id="notation-help-link" href="javascript:if(confirm(%27http://10.20.160.198/wiki/renderer/notationhelp.action \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://10.20.160.198/wiki/renderer/notationhelp.action%27" tppabs="http://10.20.160.198/wiki/renderer/notationhelp.action" onClick="window.open('http://10.20.160.198/wiki/renderer/notationhelp.action','notation_help','width=780, height=580, resizable, scrollbars'); return false;">Full notation guide</a>
</div>
</div>
</div>
<div class="comment-body">
<div id="anonymous-warning" class="noteMacro">
<img src="warning-2.gif" tppabs="http://10.20.160.198/wiki/s/en/2166/34/_/images/icons/emoticons/warning.gif" width="16" height="16" align="absmiddle">
You are not logged in. Any changes you make will be marked as <span class="smalltext">anonymous</span>.
</div>
<form name="inlinecommentform" method="post" action="http://10.20.160.198/wiki/pages/doaddcomment.action?pageId=6947109">
<input type="hidden" name="atl_token" value="c116db80711201b36e2067aa83f3b044c2d5a30e">
<fieldset class="hidden parameters">
<input type="hidden" id="contentId" value="0">
<input type="hidden" id="contentType" value="comment">
<input type="hidden" id="useWysiwyg" value="true">
<input type="hidden" id="saveDrafts" value="false">
<input type="hidden" id="draftType" value="">
<input type="hidden" id="heartbeat" value="true">
<input type="hidden" id="newPage" value="">
<input type="hidden" id="maxThumbWidth" value="200">
<input type="hidden" id="editorMode" value="markup">
<input type="hidden" id="paramsHeight" value="240">
<input type="hidden" id="isDevMode" value="false">
<input type="hidden" id="parametersName" value="content">
<input type="hidden" id="parametersId" value="content">
<input type="hidden" id="actionLocale" value="en_GB">
<input type="hidden" id="actionMarkup" value="markup">
<input type="hidden" id="actionRichtext" value="richtext">
<input type="hidden" id="actionPreview" value="preview">
<input type="hidden" id="spaceKey" value="dubbo">
<input type="hidden" id="spaceName" value="Dubbo">
<input type="hidden" id="remoteUser" value="">
<input type="hidden" id="editorPluginResourcePrefix" value="/wiki/s/en/2166/34/3.5.9/_">
<input type="hidden" title="showHiddenUserMacros" value="false">
<input type="hidden" id="gadgetPreviewWarning" value="Please complete the configuration in the preview area first">
<input type="hidden" id="attachmentSourceContentId" value="6947109"/>
<input type="hidden" id="canAttachFiles" value="false"/>
<input type="hidden" id="formName" value="inlinecommentform">
</fieldset>
<ul id="editor-tabs" class="tab-navigation">
<li id="wysiwygTab" class="tab ">
<a href="#">Rich Text</a>
</li>
<li id="markupTab" class="tab current">
<a href="#">Wiki Markup</a>
</li>
<li id="previewTab" class="tab ">
<a href="#">Preview</a>
</li>
<li id="wysiwygWaitImage" class="notab loading">Loading…</li>
</ul>
<div id="linkinserters" class="toolbar " >
<ul class="toolbar-section insert first">
<li class="toolbar-button"><a id="editor-insert-link" href="#" title="Insert/Edit Link (Ctrl+K)" class="">
<label>Insert/Edit Link (Ctrl+K)</label>
<span class="editor-icon"></span>
</a></li>
<li class="toolbar-button"><a id="editor-insert-image" href="#" title="Insert Image (Ctrl+M)" class="">
<label>Insert Image (Ctrl+M)</label>
<span class="editor-icon"></span>
</a></li>
<li class="toolbar-button"><a id="editor-insert-macro" href="#" title="Insert/Edit Macro" class="">
<label>Insert/Edit Macro</label>
<span class="editor-icon"></span>
</a></li>
</ul>
</div>
<div id="wysiwyg" class="hidden" >
<script type="text/javascript" src="tinymce.js-locale=en_GB.js" tppabs="http://10.20.160.198/wiki/s/en/2166/34/_/plugins/servlet/language/tinymce.js?locale=en_GB"></script>
<div id="rte-featured-macros" class="hidden">
<div title="Info">info</div>
<div title="Gallery">gallery</div>
<div title="Recently Updated">recently-updated</div>
<div title="Tasklist">tasklist</div>
<div title="Widget">widget</div>
<div title="Table of Contents">toc</div>
</div>
<textarea id="wysiwygTextarea" name="wysiwygcontent" class="hidden tinymce-editor"></textarea></div>
<div id="markup" >
<textarea id="markupTextarea" name="content"
cols="70"
rows="15"
tabindex="200" style=""
class="monospaceInput"
></textarea>
</div>
<input id="selectedText" name="selectedText" type="hidden">
<input type="hidden" name="sel1"> <input type="hidden" name="sel2"> <input type="hidden" name="inPreview" value="$action.inPreview"/>
<input type="hidden" name="mode" value="markup"/>
<input type="hidden" name="xhtml" value="false"/>
<div id="preview" class="hidden">
<div id="previewArea"></div>
</div>
<div id="macro-browser-templates" class="hidden">
<ol id="macro-summaries-template" class="macro-list"></ol>
<ul>
<li id="macro-summary-template" class="macro-list-item">
<h3 class="macro-title"></h3>
<div class="macro-desc"></div>
</li>
</ul>
<div id="macro-insert-template">
<input class="macro-name" type="hidden"/>
<div class="macro-preview-container dialog-panel">
<div class="macro-preview-header">
<ul class="macro-preview-links">
<li><a class="refresh-link" href="#">Refresh</a></li>
</ul>
<span>Preview</span>
</div>
<div class="macro-preview"></div>
</div>
<div class="macro-input-fields dialog-panel"></div>
</div>
<span id="macro-doco-link-template">
<a href="#" class="macro-doco-link">Documentation</a>
</span>
<div id="macro-freeform-template" class="macro-freeform-div">
<div class="macro-freeform-desc">This macro does not provide any parameter information. If the available information does not help, you may find its documentation on the <a href="javascript:if(confirm(%27https://studio.plugins.atlassian.com/wiki \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27https://studio.plugins.atlassian.com/wiki%27" tppabs="https://studio.plugins.atlassian.com/wiki">Atlassian Extensions Wiki</a>.</div>
<div class="macro-freeform-input">
{<span class="macro-name-display"></span><input type="text" class="macro-text"/>}
</div>
<div class="macro-example hidden">
<h3 class="underlined">Examples</h3>
</div>
<div class="macro-help hidden">
<h3 class="underlined">Description</h3>
</div>
</div>
<div id="macro-param-template" class="macro-param-div">
<label></label>
<input type="text" class="text"/>
</div>
<div id="macro-param-checkbox-template" class="macro-param-div boolean-param">
<label></label>
<input type="checkbox" value="true"/>
</div>
<div id="macro-param-select-template" class="macro-param-div">
<label></label>
<select></select>
</div>
<div id="macro-param-hidden-text-template" class="macro-param-div">
<label></label>
<input type="text" class="text"/>
<input type="hidden"/>
</div>
<div id="macro-param-hidden-template" class="macro-param-div">
<input type="hidden"/>
</div>
<div id="macro-param-desc-template" class="macro-param-desc"></div>
<div id="macro-body-template" class="macro-body-div">
<label>Body Text</label>
<textarea class="monospaceInput textarea" type="text" rows="10"></textarea>
</div>
<div id="macro-param-smartfield-no-suggestion-template">
<ol>
<li><a href="#" class="message"><span>No matches</span></a></li>
</ol>
</div>
<script type="text/x-template" title="macro-browser-help-link">
<div class="dialog-help-link">
<a href="http://docs.atlassian.com/confluence/docs-35/Working+with+the+Macro+Browser" target="_blank">Help</a>
</div>
</script>
<script type="text/x-template" title="macro-browser-gadget-url">
<a class='macro-uri' href='{url}' title='{url}' target='_blank'>Gadget URL</a>
</script>
</div> <script type="text/x-template" title="imageNotThumbnailable">Attached the file ‘{0}’ but no thumbnail could be displayed. The file may not be an image.</script>
<script type="text/x-template" title="attachedImages">
<div id="attached-images">
<div class="loading-message">Loading&hellip;</div>
<ul class="image-list"></ul>
</div>
<fieldset class="bottom-panel">{0}</fieldset>
</script>
<script type="text/x-template" title="imageDialogNoAttachments">
<p class="no-attachments">There are no images attached to this page.</p>
</script>
<script type="text/x-template" title="imageDialogErrorRetrievingAttachments">
<p class="warning">Error retrieving attachments from Confluence. The server may be unavailable.</p>
</script>
<script type="text/x-template" title="webImage">
<div class="insert-web-image">
<p><label>Image URL: <input type="text" class="image-url" value="http://"></label> <input type="button" class="image-preview" value="Preview"></p>
<p class="faraway image-preview-area"></p>
<p class="hidden image-preview-error">This image couldn&#8217;t be loaded for preview. Please check the URL.</p>
<p class="hidden image-preview-throbber">&nbsp;</p>
</div>
<fieldset class="bottom-panel">{0}</fieldset>
</script>
<script type="text/x-template" title="imagePropertiesForm">
<label class="align-option">Align: <select class="img-align">
<option value="none">None</option>
<option value="left">Left</option>
<option value="right">Right</option>
<option value="center">Center</option>
</select></label>
<label class="border-option"><input type="checkbox" class="img-border" checked="checked"> Border</label>
<label class="thumbnail-option"><input type="checkbox" class="img-thumbnail"> Thumbnail</label>
</script>
<script type="text/x-template" title="imageDialogImage">
<li class="attached-image">
<div class="image-container loading">
<img class="thumbnail" src="{0}" alt="" width="{1}" height="{2}" style="margin-top: {3}px">
<a href="{4}" class="zoom">Zoom</a>
</div>
<span class="caption" title="{5}">{5}</span>
</li>
</script>
<script type="text/x-template" title="insert-image-did-you-know">
<div class="dialog-tip">
Hint: type "<strong>!</strong>" in the rich text editor to insert attached images on the page.
</div>
</script>
<!-- captcha form elements -->
<div class="captcha">
<img src="jcaptcha.jpg" tppabs="http://10.20.160.198/wiki/jcaptcha" class="captcha-image" alt="CAPTCHA image" />
<div class="error" id="captchaError" style="display:none;">
<span class="errorMessage">
The typed word did not match the text in the picture.
</span>
</div>
<div class="captcha-response">
<label for="captchaResponse" class="smalltext">Please type the word appearing in the picture.</label>
<input type="text" id="captchaResponse" name="captchaResponse" value="">
</div>
</div>
<br />
<div class="submit-buttons">
<input tabindex="201" accessKey="s" type="submit" name="confirm" value="Post">
<input tabindex="202" type="submit" name="cancel" value="Cancel">
</div>
</form>
</div>
</div>
</div>
</div>
<script type="text/x-template" title="manage-watchers-dialog">
<div class="dialog-content">
<div class="column page-watchers">
<h3>Watching this page</h3>
<p class="description">These people are notified when the page is changed. You can add or remove people from this list.</p>
<form action="/wiki/json/addwatch.action" method="POST">
<input type="hidden" name="atl_token" value="c116db80711201b36e2067aa83f3b044c2d5a30e">
<input type="hidden" name="pageId" value="6947109"/>
<input type="hidden" id="add-watcher-username" name="username" value=""/>
<label for="add-watcher-user">User</label>
<input id="add-watcher-user" name="userFullName" type="search" class="autocomplete-user"
value="" placeholder="Full name or username" autocomplete="off"
data-max="10" data-target="#add-watcher-username" data-dropdown-target="#add-watcher-dropdown"
data-template="{title}" data-none-message="No matching users found.">
<input id="add-watcher-submit" type="submit" name="add" value="Add">
<div id="add-watcher-dropdown" class="aui-dd-parent autocomplete"></div>
<div class="status hidden"></div>
</form>
<ul class="user-list">
<li class="loading">Loading&hellip;</li>
<li class="no-users hidden">No page watchers</li>
</ul>
</div>
<div class="column space-watchers">
<h3>Watching this space</h3>
<p class="description">These people are notified when any content in the space is changed. You cannot modify this list.</p>
<ul class="user-list">
<li class="loading">Loading&hellip;</li>
<li class="no-users hidden">No space watchers</li>
</ul>
</div>
</div>
</script>
<script type="text/x-template" title="manage-watchers-user">
<li class="watch-user">
<img class="profile-picture confluence-userlink" src="{iconUrl}" data-username="{username}">
<a class="confluence-userlink" href="{url}" data-username="{username}">{fullName} <span class="username">({username})</span></a>
<span class="remove-watch" title="Remove"
data-username="{username}">Remove</span>
</li>
</script>
<script type="text/x-template" title="manage-watchers-help-link">
<div class="dialog-help-link">
<a href="http://docs.atlassian.com/confluence/docs-35/Managing+Watchers" target="_blank">Help</a>
</div>
</script>
<br class="clear">
</div><!-- \#main -->
<div id="footer">
<p class="license license-opensource">
Powered by a free <b>Atlassian Confluence Open Source Project License</b> granted to Alibaba Tech. <a href="javascript:if(confirm(%27http://www.atlassian.com/c/conf/11461 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://www.atlassian.com/c/conf/11461%27" tppabs="http://www.atlassian.com/c/conf/11461">Evaluate Confluence today</a>.<br>
</p>
<ul id="poweredby">
<li class="noprint">Powered by <a href="javascript:if(confirm(%27http://www.atlassian.com/software/confluence \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://www.atlassian.com/software/confluence%27" tppabs="http://www.atlassian.com/software/confluence" class="hover-footer-link">Atlassian Confluence</a> 3.5.9, the <a href="javascript:if(confirm(%27http://www.atlassian.com/software/confluence/tour/enterprise-wiki.jsp \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://www.atlassian.com/software/confluence/tour/enterprise-wiki.jsp%27" tppabs="http://www.atlassian.com/software/confluence/tour/enterprise-wiki.jsp" class="hover-footer-link">Enterprise Wiki</a></li>
<li class="print-only">Printed by Atlassian Confluence 3.5.9, the Enterprise Wiki.</li>
<li class="noprint"> &nbsp; |&nbsp; <a href="javascript:if(confirm(%27http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470 \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470%27" tppabs="http://jira.atlassian.com/secure/BrowseProject.jspa?id=10470" class="hover-footer-link">Report a bug</a></li>
<li class="noprint"> &nbsp;|&nbsp; <a href="javascript:if(confirm(%27http://www.atlassian.com/about/connected.jsp?s_kwcid=Confluence-stayintouch \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://www.atlassian.com/about/connected.jsp?s_kwcid=Confluence-stayintouch%27" tppabs="http://www.atlassian.com/about/connected.jsp?s_kwcid=Confluence-stayintouch" class="hover-footer-link">Atlassian News</a></li>
</ul>
友情链接:<a href="javascript:if(confirm(%27http://code.taobao.org/ \n\nThis file was not retrieved by Teleport Ultra, because it is addressed on a domain or path outside the boundaries set for its Starting Address. \n\nDo you want to open it from the server?%27))window.location=%27http://code.taobao.org/%27" tppabs="http://code.taobao.org/">Taocode</a>
<script type="text/javascript">
var _gaq = _gaq || [];
_gaq.push(['_setAccount', 'UA-31474478-1']);
_gaq.push(['_trackPageview']);
(function() {
var ga = document.createElement('script'); ga.type = 'text/javascript'; ga.async = true;
ga.src = ('https:' == document.location.protocol ? 'https://ssl' : 'http://www/') + '.google-analytics.com/ga.js';
var s = document.getElementsByTagName('script')[0]; s.parentNode.insertBefore(ga, s);
})();
</script>
</div></div><!-- \#full-height-container -->
</div><!-- \#page -->
</body>
</html>