blob: a871ea83e1c7bd32df56631434b61f3867f6b4de [file] [log] [blame]
<!doctype html>
<!--
Minimal Mistakes Jekyll Theme 4.4.1 by Michael Rose
Copyright 2017 Michael Rose - mademistakes.com | @mmistakes
Free for personal and commercial use under the MIT license
https://github.com/mmistakes/minimal-mistakes/blob/master/LICENSE.txt
-->
<html lang="cn" class="no-js">
<head>
<meta charset="utf-8">
<!-- begin SEO -->
<title>部署模式 - Apache ServiceComb</title>
<meta name="description" content="部署模式">
<meta name="author" content="">
<meta property="og:locale" content="cn">
<meta property="og:site_name" content="Apache ServiceComb">
<meta property="og:title" content="部署模式">
<link rel="canonical" href="https://github.com/pages/apache/incubator-servicecomb-website/cn/docs/users/deploy-mode/">
<meta property="og:url" content="https://github.com/pages/apache/incubator-servicecomb-website/cn/docs/users/deploy-mode/">
<meta property="og:description" content="部署模式">
<meta name="twitter:site" content="@ServiceComb">
<meta name="twitter:title" content="部署模式">
<meta name="twitter:description" content="部署模式">
<meta name="twitter:url" content="">
<meta name="twitter:card" content="summary">
<script type="application/ld+json">
{
"@context" : "http://schema.org",
"@type" : "Person",
"name" : "Apache ServiceComb",
"url" : "https://github.com/pages/apache/incubator-servicecomb-website",
"sameAs" : null
}
</script>
<meta name="google-site-verification" content="HvJjNd7vvJ-yjSTHlBiIWEYxp_Hrz-PYEY5Idz9LRcA" />
<!-- end SEO -->
<link href="/feed.xml" type="application/atom+xml" rel="alternate" title="Apache ServiceComb Feed">
<!-- http://t.co/dKP3o1e -->
<meta name="HandheldFriendly" content="True">
<meta name="MobileOptimized" content="320">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<script>
document.documentElement.className = document.documentElement.className.replace(/\bno-js\b/g, '') + ' js ';
</script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/clipboard.js/1.7.1/clipboard.min.js"></script>
<script src="/assets/vendor/prism/prism.js"></script>
<script type="text/javascript" async
src="https://cdnjs.cloudflare.com/ajax/libs/mathjax/2.7.1/MathJax.js?config=TeX-MML-AM_CHTML">
</script>
<link rel="stylesheet" href="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/css/bootstrap.min.css" integrity="sha384-/Y6pD6FV/Vv2HJnA6t+vslU6fwYXjCFtcEpHbNJ0lyAFsXTsjBbfaDjzALeQsN6M" crossorigin="anonymous">
<script src="https://code.jquery.com/jquery-3.2.1.slim.min.js" integrity="sha384-KJ3o2DKtIkvYIK3UENzmM7KCkRr/rE9/Qpg6aAZGJwFDMVNA/GpGFF93hXpG5KkN" crossorigin="anonymous"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.11.0/umd/popper.min.js" integrity="sha384-b/U6ypiBEHpOf/4+1nzFpr53nxSS+GLCkfwBdFNTxtclqqenISfwAzpKaMNFNmj4" crossorigin="anonymous"></script>
<script src="https://maxcdn.bootstrapcdn.com/bootstrap/4.0.0-beta/js/bootstrap.min.js" integrity="sha384-h0AbiXch4ZDo7tp9hKZ4TsHbi047NrKGLO3SEJAg45jXxnGIfYzk4Si90RDIqNm1" crossorigin="anonymous"></script>
<!-- For all browsers -->
<link rel="stylesheet" href="/assets/css/main.css">
<link rel="stylesheet" href="/assets/vendor/prism/prism.css">
<!--[if lte IE 9]>
<style>
/* old IE unsupported flexbox fixes */
.greedy-nav .site-title {
padding-right: 3em;
}
.greedy-nav button {
position: absolute;
top: 0;
right: 0;
height: 100%;
}
</style>
<![endif]-->
<meta http-equiv="cleartype" content="on">
<!-- start custom head snippets -->
<!-- insert favicons. use http://realfavicongenerator.net/ -->
<link href="https://fonts.loli.net/css?family=Roboto:400,500,700|Source+Code+Pro" rel="stylesheet">
<script src="/assets/js/custom.js"></script>
<!-- end custom head snippets -->
</head>
<body class="layout--single">
<!--[if lt IE 9]>
<div class="notice--danger align-center" style="margin: 0;">You are using an <strong>outdated</strong> browser. Please <a href="http://browsehappy.com/">upgrade your browser</a> to improve your experience.</div>
<![endif]-->
<div class="masthead" onmouseleave="$('#childrenShow').css('display', 'none')">
<div class="masthead__inner-wrap">
<div class="masthead__menu">
<nav id="site-nav" class="greedy-nav">
<a class="site-title active" href="/cn"><img src="https://www.apache.org/img/servicecomb.png"></a>
<ul class="visible-links">
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/cn/">首页</a>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/cn/developers/">项目</a>
</li>
<li class="def-nav-li" onmouseenter="$('#childrenShow').css('display', 'block')">
<a class="active" href="/cn/docs/users/">文档</a>
<ul id="childrenShow" class="def-children-show-cn" onmouseleave="$('#childrenShow').css('display', 'none')">
<li><a href="/cn/docs/getting-started/" class="">入门指南</a></li>
<li><a href="/cn/docs/users/" class="">用户手册</a></li>
<li><a href="/cn/slides/" class="">大咖视频</a></li>
<li><a href="/cn/faqs/" class="">常见问题</a></li>
</ul>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/cn/developers/contributing/">社区</a>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/cn/year-archive/">博文</a>
</li>
<li class="masthead__menu-item" onmouseenter="$('#childrenShow').css('display', 'none')">
<a href="/cn/release/">下载</a>
</li>
</ul>
<button><div class="navicon"></div></button>
<ul class="hidden-links hidden"></ul>
<div class="nav-lang">
<a href=/docs/users/deploy-mode/>English</a>
</div>
</nav>
</div>
</div>
</div>
<div id="main" role="main">
<div class="sidebar sticky">
<div class="back-to-home"><a href="/cn/">首页</a> > 部署模式</div>
<nav class="nav__list">
<input id="ac-toc" name="accordion-toc" type="checkbox" />
<label for="ac-toc">切换菜单</label>
<ul class="nav__items">
<li>
<span class="nav__sub-title">Java-chassis用户手册</span>
<ul>
<li><a href="/references/java-chassis/en_US/" class="">2.3.0</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Pack用户手册</span>
<ul>
<li><a href="https://github.com/apache/servicecomb-pack/blob/master/docs/user_guide.md" class="">0.5.0(英文版)</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">ServiceCenter用户手册</span>
<ul>
<li><a href="https://service-center.readthedocs.io/en/latest/user-guides.html" class="">2.0.0(英文版)</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Kie 用户手册</span>
<ul>
<li><a href="https://kie.readthedocs.io/en/latest/" class="">0.2.0(英文版)</a></li>
</ul>
</li>
<li>
<span class="nav__sub-title">Mesher 用户手册</span>
<ul>
<li><a href="https://mesher.readthedocs.io/en/latest/" class="">1.6.3(英文版)</a></li>
</ul>
</li>
</ul>
</nav>
</div>
<article class="page" itemscope itemtype="http://schema.org/CreativeWork">
<meta itemprop="headline" content="部署模式">
<meta itemprop="description" content="部署模式">
<meta itemprop="dateModified" content="May 25, 2018">
<div class="page__inner-wrap">
<header>
<h1 class="page__title" itemprop="headline">部署模式
</h1>
</header>
<section class="page__content" itemprop="text">
<aside class="sidebar__right">
<nav class="toc">
<!-- <header><h4 class="nav__title"><i class="fa fa-file-text"></i> 在本页上</h4></header> -->
<ul class="toc__menu" id="markdown-toc">
<li><a href="#物理机或虚拟机部署" id="markdown-toc-物理机或虚拟机部署">物理机或虚拟机部署</a> <ul>
<li><a href="#如何打包微服务" id="markdown-toc-如何打包微服务">如何打包微服务</a></li>
</ul>
</li>
<li><a href="#docker容器化部署" id="markdown-toc-docker容器化部署">Docker容器化部署</a> <ul>
<li><a href="#如何直接打包微服务为docker镜像" id="markdown-toc-如何直接打包微服务为docker镜像">如何直接打包微服务为Docker镜像</a></li>
<li><a href="#使用docker-compose编排并拉起所有的微服务" id="markdown-toc-使用docker-compose编排并拉起所有的微服务">使用Docker Compose编排并拉起所有的微服务</a></li>
</ul>
</li>
<li><a href="#kubernetes集群部署" id="markdown-toc-kubernetes集群部署">Kubernetes集群部署</a> <ul>
<li><a href="#kubernetes" id="markdown-toc-kubernetes">Kubernetes</a></li>
<li><a href="#java-chassis" id="markdown-toc-java-chassis">Java Chassis</a></li>
<li><a href="#kubernetes--java-chassis" id="markdown-toc-kubernetes--java-chassis">Kubernetes + Java Chassis</a></li>
<li><a href="#在kubernetes集群中部署java-chassis-company演示项目" id="markdown-toc-在kubernetes集群中部署java-chassis-company演示项目">在Kubernetes集群中部署Java Chassis Company演示项目</a></li>
</ul>
</li>
</ul>
</nav>
</aside>
<p>Java Chassis作为一个微服务框架,支持多样化的部署模式。</p>
<h2 id="物理机或虚拟机部署">物理机或虚拟机部署</h2>
<p>这种方式直接部署在物理机或虚拟机操作系统上,Chassis微服务以Java进程的方式启动:</p>
<p><img src="/assets/images/SimpleDeployment.png" alt="SimpleDeployment" /></p>
<p>请保证网络在同一个局域网内,或能互通。</p>
<h3 id="如何打包微服务">如何打包微服务</h3>
<p>在微服务项目的<code class="language-plaintext highlighter-rouge">pom.xml</code>中添加以下依赖:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt">&lt;build&gt;</span>
<span class="nt">&lt;plugins&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>maven-jar-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>2.6<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
<span class="nt">&lt;archive&gt;</span>
<span class="nt">&lt;manifest&gt;</span>
<span class="nt">&lt;addClasspath&gt;</span>true<span class="nt">&lt;/addClasspath&gt;</span>
<span class="nt">&lt;classpathPrefix&gt;</span>lib/<span class="nt">&lt;/classpathPrefix&gt;</span>
<span class="c">&lt;!--change to your main class--&gt;</span>
<span class="nt">&lt;mainClass&gt;</span>${your-package}.Application<span class="nt">&lt;/mainClass&gt;</span>
<span class="nt">&lt;/manifest&gt;</span>
<span class="nt">&lt;manifestEntries&gt;</span>
<span class="nt">&lt;Class-Path&gt;</span>. <span class="nt">&lt;/Class-Path&gt;</span>
<span class="nt">&lt;/manifestEntries&gt;</span>
<span class="nt">&lt;/archive&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>maven-dependency-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;executions&gt;</span>
<span class="nt">&lt;execution&gt;</span>
<span class="nt">&lt;id&gt;</span>copy-dependencies<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;phase&gt;</span>package<span class="nt">&lt;/phase&gt;</span>
<span class="nt">&lt;goals&gt;</span>
<span class="nt">&lt;goal&gt;</span>copy-dependencies<span class="nt">&lt;/goal&gt;</span>
<span class="nt">&lt;/goals&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
<span class="nt">&lt;outputDirectory&gt;</span>target/lib<span class="nt">&lt;/outputDirectory&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;/execution&gt;</span>
<span class="nt">&lt;/executions&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;/plugins&gt;</span>
<span class="nt">&lt;/build&gt;</span>
</code></pre></div></div>
<p>之后运行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package
</code></pre></div></div>
<p><code class="language-plaintext highlighter-rouge">target</code>目录下拷贝生成的微服务jar包和<code class="language-plaintext highlighter-rouge">lib</code>(依赖jar)至任何目录,运行即可:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>java <span class="nt">-jar</span> <span class="k">${</span><span class="nv">project</span><span class="p">.artifactId</span><span class="k">}</span>-<span class="k">${</span><span class="nv">project</span><span class="p">.version</span><span class="k">}</span>.jar
</code></pre></div></div>
<blockquote>
<p>提示:</p>
<ol>
<li>如果需要更改<code class="language-plaintext highlighter-rouge">microservice.yaml</code>中的配置项又不希望重新打包,可以直接编写一个新的<code class="language-plaintext highlighter-rouge">microservice.yaml</code>,然后放置于微服务jar包同级别目录,重启微服务即可;</li>
<li>请修改上面打包依赖配置中<code class="language-plaintext highlighter-rouge">&lt;mainClass&gt;${your-package}.Application&lt;/mainClass&gt;</code>为微服务启动MainClass。</li>
</ol>
</blockquote>
<h2 id="docker容器化部署">Docker容器化部署</h2>
<p>这种方式适合部署测试环境,当微服务数据量比较多的情况下能够大幅减少部署的工作量,一键拉起所有的微服务:</p>
<p><img src="/assets/images/DockerDeployment.png" alt="DockerDeployment" /></p>
<h3 id="如何直接打包微服务为docker镜像">如何直接打包微服务为Docker镜像</h3>
<p>我们使用io.fabric8的<a href="https://github.com/fabric8io/docker-maven-plugin">maven插件</a>从打包,镜像在微服务项目的<code class="language-plaintext highlighter-rouge">pom.xml</code>中添加以下依赖:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code> <span class="nt">&lt;build&gt;</span>
<span class="nt">&lt;pluginManagement&gt;</span>
<span class="nt">&lt;plugins&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>io.fabric8<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>docker-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
<span class="nt">&lt;images&gt;</span>
<span class="nt">&lt;image&gt;</span>
<span class="nt">&lt;name&gt;</span>${project.artifactId}:${project.version}<span class="nt">&lt;/name&gt;</span>
<span class="nt">&lt;alias&gt;</span>${project.artifactId}<span class="nt">&lt;/alias&gt;</span>
<span class="nt">&lt;build&gt;</span>
<span class="nt">&lt;from&gt;</span>openjdk:8-jdk-stretch<span class="nt">&lt;/from&gt;</span>
<span class="nt">&lt;ports&gt;</span>
<span class="nt">&lt;port&gt;</span>8080<span class="nt">&lt;/port&gt;</span>
<span class="nt">&lt;/ports&gt;</span>
<span class="nt">&lt;volumes&gt;</span>
<span class="nt">&lt;volume&gt;</span>/docker<span class="nt">&lt;/volume&gt;</span>
<span class="nt">&lt;/volumes&gt;</span>
<span class="nt">&lt;assembly&gt;</span>
<span class="nt">&lt;mode&gt;</span>dir<span class="nt">&lt;/mode&gt;</span>
<span class="nt">&lt;basedir&gt;</span>/<span class="nt">&lt;/basedir&gt;</span>
<span class="nt">&lt;descriptor&gt;</span>assembly.xml<span class="nt">&lt;/descriptor&gt;</span>
<span class="nt">&lt;/assembly&gt;</span>
<span class="nt">&lt;entryPoint&gt;</span>
<span class="nt">&lt;shell&gt;</span>java $JAVA_OPTS -jar /docker/${project.artifactId}-${project.version}.jar<span class="nt">&lt;/shell&gt;</span>
<span class="nt">&lt;/entryPoint&gt;</span>
<span class="nt">&lt;/build&gt;</span>
<span class="nt">&lt;/image&gt;</span>
<span class="nt">&lt;/images&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;executions&gt;</span>
<span class="nt">&lt;execution&gt;</span>
<span class="nt">&lt;id&gt;</span>build<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;phase&gt;</span>package<span class="nt">&lt;/phase&gt;</span>
<span class="nt">&lt;goals&gt;</span>
<span class="nt">&lt;goal&gt;</span>build<span class="nt">&lt;/goal&gt;</span>
<span class="nt">&lt;/goals&gt;</span>
<span class="nt">&lt;/execution&gt;</span>
<span class="nt">&lt;/executions&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;/plugins&gt;</span>
<span class="nt">&lt;/pluginManagement&gt;</span>
<span class="nt">&lt;/build&gt;</span>
<span class="nt">&lt;profiles&gt;</span>
<span class="nt">&lt;profile&gt;</span>
<span class="nt">&lt;id&gt;</span>docker<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;build&gt;</span>
<span class="nt">&lt;plugins&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>maven-jar-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;version&gt;</span>2.6<span class="nt">&lt;/version&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
<span class="nt">&lt;archive&gt;</span>
<span class="nt">&lt;manifest&gt;</span>
<span class="nt">&lt;addClasspath&gt;</span>true<span class="nt">&lt;/addClasspath&gt;</span>
<span class="nt">&lt;classpathPrefix&gt;</span>lib/<span class="nt">&lt;/classpathPrefix&gt;</span>
<span class="c">&lt;!--change to your main class--&gt;</span>
<span class="nt">&lt;mainClass&gt;</span>${your-package}.Application<span class="nt">&lt;/mainClass&gt;</span>
<span class="nt">&lt;/manifest&gt;</span>
<span class="nt">&lt;manifestEntries&gt;</span>
<span class="nt">&lt;Class-Path&gt;</span>.<span class="nt">&lt;/Class-Path&gt;</span>
<span class="nt">&lt;/manifestEntries&gt;</span>
<span class="nt">&lt;/archive&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>org.apache.maven.plugins<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>maven-dependency-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;executions&gt;</span>
<span class="nt">&lt;execution&gt;</span>
<span class="nt">&lt;id&gt;</span>copy-dependencies<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;phase&gt;</span>package<span class="nt">&lt;/phase&gt;</span>
<span class="nt">&lt;goals&gt;</span>
<span class="nt">&lt;goal&gt;</span>copy-dependencies<span class="nt">&lt;/goal&gt;</span>
<span class="nt">&lt;/goals&gt;</span>
<span class="nt">&lt;configuration&gt;</span>
<span class="nt">&lt;outputDirectory&gt;</span>target/lib<span class="nt">&lt;/outputDirectory&gt;</span>
<span class="nt">&lt;/configuration&gt;</span>
<span class="nt">&lt;/execution&gt;</span>
<span class="nt">&lt;/executions&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;plugin&gt;</span>
<span class="nt">&lt;groupId&gt;</span>io.fabric8<span class="nt">&lt;/groupId&gt;</span>
<span class="nt">&lt;artifactId&gt;</span>docker-maven-plugin<span class="nt">&lt;/artifactId&gt;</span>
<span class="nt">&lt;/plugin&gt;</span>
<span class="nt">&lt;/plugins&gt;</span>
<span class="nt">&lt;/build&gt;</span>
<span class="nt">&lt;/profile&gt;</span>
<span class="nt">&lt;/profiles&gt;</span>
</code></pre></div></div>
<p>在项目源代码<code class="language-plaintext highlighter-rouge">src\main</code>下,创建一个<code class="language-plaintext highlighter-rouge">docker</code>目录,之后在此目录中创建一个<code class="language-plaintext highlighter-rouge">assembly.xml</code>文件,填入下面的内容:</p>
<div class="language-xml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="cp">&lt;?xml version="1.0" encoding="UTF-8"?&gt;</span>
<span class="nt">&lt;assembly&gt;</span>
<span class="nt">&lt;id&gt;</span>installer<span class="nt">&lt;/id&gt;</span>
<span class="nt">&lt;fileSets&gt;</span>
<span class="nt">&lt;fileSet&gt;</span>
<span class="nt">&lt;directory&gt;</span>${project.build.directory}/lib<span class="nt">&lt;/directory&gt;</span>
<span class="nt">&lt;outputDirectory&gt;</span>/docker/lib<span class="nt">&lt;/outputDirectory&gt;</span>
<span class="nt">&lt;fileMode&gt;</span>0644<span class="nt">&lt;/fileMode&gt;</span>
<span class="nt">&lt;directoryMode&gt;</span>0755<span class="nt">&lt;/directoryMode&gt;</span>
<span class="nt">&lt;/fileSet&gt;</span>
<span class="nt">&lt;/fileSets&gt;</span>
<span class="nt">&lt;files&gt;</span>
<span class="nt">&lt;file&gt;</span>
<span class="nt">&lt;source&gt;</span>${project.build.directory}/${project.artifactId}-${project.version}.jar<span class="nt">&lt;/source&gt;</span>
<span class="nt">&lt;outputDirectory&gt;</span>/docker<span class="nt">&lt;/outputDirectory&gt;</span>
<span class="nt">&lt;destName&gt;</span>${project.artifactId}-${project.version}.jar<span class="nt">&lt;/destName&gt;</span>
<span class="nt">&lt;/file&gt;</span>
<span class="nt">&lt;/files&gt;</span>
<span class="nt">&lt;/assembly&gt;</span>
</code></pre></div></div>
<p>完成之后的项目效果:</p>
<p><img src="/assets/images/DockerPackageAssembly.png" alt="DockerPackageAssembly" /></p>
<p>运行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn package <span class="nt">-Pdocker</span>
</code></pre></div></div>
<p>等待打包完成,会有提示镜像生成成功并注册到本地镜像库的提示。</p>
<blockquote>
<p>提示:</p>
<ol>
<li>请修改上面打包依赖配置中<code class="language-plaintext highlighter-rouge">&lt;mainClass&gt;${your-package}.Application&lt;/mainClass&gt;</code>为微服务启动MainClass;</li>
<li>为了保留普通打包方式,docker打包方式配置为maven profile,即``-Pdocker`;</li>
<li>如果是使用windows系统,请安装docker machine,并且确保docker machine vm启动中;</li>
<li>打包的镜像会默认安装在本地镜像库中,如果需要上传外部镜像库例如中央库,可以使用下面的命令:
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>mvn <span class="nt">-Ddocker</span>.registry<span class="o">=</span>registry.hub.docker.com/<span class="k">${</span><span class="nv">username</span><span class="k">}</span> <span class="nt">-Ddocker</span>.username<span class="o">=</span><span class="k">${</span><span class="nv">username</span><span class="k">}</span> <span class="nt">-Ddocker</span>.password<span class="o">=</span><span class="k">${</span><span class="nv">password</span><span class="k">}</span> docker:push
</code></pre></div> </div>
</li>
</ol>
</blockquote>
<h3 id="使用docker-compose编排并拉起所有的微服务">使用Docker Compose编排并拉起所有的微服务</h3>
<p>将所有的微服务打包为镜像后,就可以使用Docker Compose组织它们,我们给一个例子:</p>
<div class="language-yaml highlighter-rouge"><div class="highlight"><pre class="highlight"><code><span class="na">version</span><span class="pi">:</span> <span class="s1">'</span><span class="s">2.0'</span>
<span class="na">services</span><span class="pi">:</span>
<span class="na">service-center</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s2">"</span><span class="s">servicecomb/service-center"</span>
<span class="na">hostname</span><span class="pi">:</span> <span class="s">service-center</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">30100:30100"</span>
<span class="na">mysql-write-db</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s2">"</span><span class="s">mysql:latest"</span>
<span class="na">hostname</span><span class="pi">:</span> <span class="s">write_db_server</span>
<span class="na">environment</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">MYSQL_ROOT_PASSWORD=password</span>
<span class="pi">-</span> <span class="s">MYSQL_DATABASE=seckill</span>
<span class="pi">-</span> <span class="s">MYSQL_USER=seckill</span>
<span class="pi">-</span> <span class="s">MYSQL_PASSWORD=password</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">3306"</span>
<span class="na">activemq</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s2">"</span><span class="s">webcenter/activemq:latest"</span>
<span class="na">hostname</span><span class="pi">:</span> <span class="s">queue-server</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">61616"</span>
<span class="na">admin-service</span><span class="pi">:</span>
<span class="na">image</span><span class="pi">:</span> <span class="s2">"</span><span class="s">seckill-admin-service:0.2.0-SNAPSHOT"</span>
<span class="na">hostname</span><span class="pi">:</span> <span class="s">admin-service</span>
<span class="na">links</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">mysql-write-db:write_db.servicecomb.io"</span>
<span class="na">environment</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s">JAVA_OPTS=-Dspring.profiles.active=prd,cse -Dendpoints.shutdown.enabled=true</span>
<span class="na">ports</span><span class="pi">:</span>
<span class="pi">-</span> <span class="s2">"</span><span class="s">8081:8081"</span>
</code></pre></div></div>
<p>为了能够使containers互联互通,使用<code class="language-plaintext highlighter-rouge">links</code>指定链接关系,<code class="language-plaintext highlighter-rouge">ports</code>用于映射到Docker Host的端口,关于Docker Compose Yaml配置的更多信息,可以参见<a href="https://docs.docker.com/compose/">这篇文档</a></p>
<p>编写好docker-compose.yml后,切换到此文件目录,执行:</p>
<div class="language-bash highlighter-rouge"><div class="highlight"><pre class="highlight"><code>docker-compose up
</code></pre></div></div>
<p>即可将所有的微服务都拉起来。</p>
<blockquote>
<p>提示:</p>
<ol>
<li>docker-compose默认寻找当前文件夹下的docker-compose.yml文件作为编排配置文件,如果需要指定文件名或路径,请使用<code class="language-plaintext highlighter-rouge">docker-compose -f ${fullFileName}</code></li>
<li>如果container无需对外发布端口则可以不设置<code class="language-plaintext highlighter-rouge">ports</code></li>
</ol>
</blockquote>
<h2 id="kubernetes集群部署">Kubernetes集群部署</h2>
<p>Kubernetes是谷歌开源的容器集群管理系统,目前已经具备生产化成熟度,虽然Java Chassis作为一个微服务框架与Kubernetes处于不同层次,但由于Kubernetes同样拥有注册-发现、弹性伸缩、监控等方面的功能,因此很容易与Java Chassis中相关功能搞混,我们需要比较深入的理解两者的差异。</p>
<h3 id="kubernetes">Kubernetes</h3>
<p><img src="/assets/images/K8S.png" alt="K8S" /></p>
<p>上图中,我们省去了网络细节,关注这几个点:</p>
<ol>
<li>Service的注册和发现:应用(app)实例(container)的启动或停止由Kubernetes管理,Kubernetes会依据Node的负载状况动态调配Host它们的Pod,那么这就带来一个问题:一个App想调用另外一个App,是如何知道目标App实例的IP和端口呢?因此Kubernetes引入了一个逻辑层次——Service,Service有唯一的名字,Kubernetes会将Service的所有App实例在Pod上的IP和端口保存在Name Service中,如果App之间的调用通过Service名,就可以通过Service名映射app实例的IP和端口,这个过程类似DNS。Kubernetes启动App实例并向Name Service登记的这个过程就是Service的注册,而一个App调用另外一个App从Name Service查询目标IP和端口的过程就是Service的发现;</li>
<li>弹性伸缩:弹性伸缩是Kubernetes的一个重要能力,通过配置弹性伸缩策略,支持使用CPU、内存使用率、连接数,或其他第三方的Metrics作为输入,如何设置请参考<a href="https://k8smeetup.github.io/docs/tasks/run-application/horizontal-pod-autoscale-walkthrough/">这篇文档</a></li>
<li>负载均衡:有了Service注册和发现机制,Kubernetes以Service Name为中心构建负载均衡,Service有三种类型<code class="language-plaintext highlighter-rouge">NodePort</code><code class="language-plaintext highlighter-rouge">ClusterIP</code><code class="language-plaintext highlighter-rouge">LoadBalancer</code>,后两种具有负载均衡能力,<code class="language-plaintext highlighter-rouge">LoadBalancer</code>需要PaaS平台实现,因此对于本地Kubernetes集群多用<code class="language-plaintext highlighter-rouge">ClusterIP</code></li>
<li>监控:Kubernetes自带Heapster监控资源的使用。</li>
</ol>
<h3 id="java-chassis">Java Chassis</h3>
<p><img src="/assets/images/ServiceCombBasic.png" alt="ServiceCombBasic" /></p>
<p>上图是Java Chassis基本原理,我们同样解释几个点:</p>
<ol>
<li>Java Chassis的注册和发现:ServiceCenter是一个完整独立的注册中心,不同于Kubernetes的Name Service,它存储了微服务启动后上传的Swagger契约,契约中描述了调用路径、入参和出参,即对接口进行了全面的描述。其它微服务发起调用的时候,可以通过获取Producer的契约动态生成Consumer代码,也可以做调用预检查等;</li>
<li>弹性伸缩:Java Chassis作为一个SDK本身是无法启动微服务实例和调配资源的,因此没有此能力。</li>
<li>负载均衡:Java Chassis是Consumer端软负载均衡;当一个Java Chassis微服务启动后,会将获取的本地IP和设置的发布端口发布至ServiceCenter,ServiceCenter会立刻通知所有的其他微服务实例信息发生了变化,更新本地缓存,调整负载分配;</li>
<li>监控:Java Chassis并不带监控系统,它只可以输出Tracing、Metrics和Log数据,对接Zipkin、Prometheus等监控系统,当然Metrics也可以作为Kubernetes弹性伸缩策略的输入。</li>
</ol>
<p>综合上述,我们总结为下面的表格:</p>
<table>
<thead>
<tr>
<th style="text-align: left">说明项</th>
<th style="text-align: left">Kubernetes</th>
<th style="text-align: left">Java Chassis</th>
</tr>
</thead>
<tbody>
<tr>
<td style="text-align: left">定位</td>
<td style="text-align: left">容器集群管理系统</td>
<td style="text-align: left">微服务框架</td>
</tr>
<tr>
<td style="text-align: left">层次</td>
<td style="text-align: left">PaaS</td>
<td style="text-align: left">SDK</td>
</tr>
<tr>
<td style="text-align: left">Service的含义</td>
<td style="text-align: left">逻辑概念,用selector指向containers</td>
<td style="text-align: left">业务概念,微服务拆分后的业务</td>
</tr>
<tr>
<td style="text-align: left">注册和发现</td>
<td style="text-align: left">NameService为中心</td>
<td style="text-align: left">ServiceCenter为中心</td>
</tr>
<tr>
<td style="text-align: left">弹性伸缩</td>
<td style="text-align: left">调度资源启动或停止实例</td>
<td style="text-align: left">无此能力</td>
</tr>
<tr>
<td style="text-align: left">负载均衡</td>
<td style="text-align: left">name + selector机制</td>
<td style="text-align: left">Consumer端动态发现实例的变化</td>
</tr>
<tr>
<td style="text-align: left">监控</td>
<td style="text-align: left">有集成的监控系统</td>
<td style="text-align: left">只作为监控系统的数据源</td>
</tr>
</tbody>
</table>
<h3 id="kubernetes--java-chassis">Kubernetes + Java Chassis</h3>
<p>理解了上面的内容之后,我们可以如下设计 Java Chassis在Kubernetes集群中的部署:</p>
<p><img src="/assets/images/ServiceCombInK8S.png" alt="ServiceCombInK8S" /></p>
<ul>
<li>将微服务的镜像上传至Kubernetes能够访问到的镜像仓库;</li>
<li>为每一个 Java Chassis微服务配置为一个Kubernetes Deployment并配置弹性伸缩策略;</li>
<li>ServerCenter如果作为一个Kubernetes Deployment部署,那么保证IP固定使得VPC内均可访问,也可以将ServiceCenter部署在外部,然后使用Kubernetes外部域名解析机制能够访问到它;</li>
<li>使用Fannel网络让Pod的IP能够互联互通, Java Chassis启动后会使用Pod的IP发布,保证能相互调用;否则配置使用<code class="language-plaintext highlighter-rouge">servicecomb.service.publishAddress</code>指定发布地址;</li>
<li>对于需要外部访问的 Java Chassis微服务,配置Kubernetes Service。</li>
</ul>
<blockquote>
<p>提示:</p>
<ol>
<li>请牢记 Java Chassis的负载均衡机制与Kubernetes的负载均衡机制无关,即Java Chassis的负载均衡并不走name + selector机制,也不需要配置Service;</li>
<li>上述部署细节可依据实际环境(例如网络)自行调整。</li>
</ol>
</blockquote>
<h3 id="在kubernetes集群中部署java-chassis-company演示项目">在Kubernetes集群中部署Java Chassis Company演示项目</h3>
<p>Company是我们提供的一个有趣味性的演示项目:</p>
<ol>
<li>源代码地址:https://github.com/huaweicse/ServiceComb-Company-WorkShop</li>
<li>项目的详细讲解:http://servicecomb.apache.org/cn/docs/linuxcon-workshop-demo/</li>
</ol>
<p>如何在Kubernetes集群中部署Company:http://servicecomb.apache.org/cn/docs/company-on-kubernetes/</p>
</section>
<footer class="page__meta">
</footer>
</div>
</article>
</div>
<script async src="//pagead2.googlesyndication.com/pagead/js/adsbygoogle.js"></script>
<div align="center" style="margin: 0 0;">
<ins class="adsbygoogle"
style="display:block; border-bottom: initial;"
data-ad-client="ca-pub-7328585512091257"
data-ad-slot="3049671934"
data-ad-format="auto"></ins>
</div>
<div class="page__footer">
<footer>
<!-- start custom footer snippets -->
<!-- end custom footer snippets -->
<div class="container">
<div class="row justify-content-md-center">
<div class="col">
<ul>
<p class="header">资源</p>
<li><a href="/cn/docs/getting-started/">入门指南</a></li>
<li><a href="/cn/docs/users/">用户指南</a></li>
<li><a href="/cn/slides/">资料</a></li>
<li><a href="/cn/users/faq/">常见问题</a></li>
</ul>
</div>
<div class="col">
<ul>
<p class="header">ASF</p>
<li><a href="http://www.apache.org">基金会</a></li>
<li><a href="http://www.apache.org/licenses/">许可证</a></li>
<li><a href="http://www.apache.org/events/current-event">活动</a></li>
<li><a href="http://www.apache.org/foundation/sponsorship.html">赞助</a></li>
<li><a href="http://www.apache.org/foundation/thanks.html">鸣谢</a></li>
</ul>
</div>
<div class="col">
<ul>
<p class="header">贡献</p>
<li><a href="http://issues.apache.org/jira/browse/SCB">报告本网页问题</a></li>
<li><a href="https://github.com/apache/servicecomb-website/edit/master/_users/cn/deploy-mode.md">在Github上编辑此页</a></li>
<li><a href="/cn/developers/submit-codes/">代码提交指南</a></li>
<li><a href="/cn/security">安全</a></li>
</ul>
</div>
<div class="col">
<ul class="social-icons">
<p class="header">社区</p>
<li>
<a href="mailto:dev-subscribe@servicecomb.incubator.apache.org" rel="nofollow"><span class="mail">邮件列表</span></a>
</li>
<li>
<a href="https://github.com/apache?q=ServiceComb" target="_blank"><span class="github">Github</span></a>
</li>
<li>
<a href="https://twitter.com/ServiceComb" target="_blank"><span class="twitter">Twitter</span></a>
</li>
<li>
<a href="/feed.xml" target="_blank"><span class="rss">Feed</span></a>
</li>
</ul>
</div>
</div>
</div>
<div class="page__footer-bottom">
<div>&copy; 2021 Apache ServiceComb. 技术来自于 <a href="http://jekyllrb.com" rel="nofollow">Jekyll</a> &amp; <a href="https://mademistakes.com/work/minimal-mistakes-jekyll-theme/" rel="nofollow">Minimal Mistakes</a>.</div>
<div>All other marks mentioned may be trademarks or registered trademarks of their respective owners.</div>
</div>
</footer>
</div>
<script src="/assets/js/main.min.js"></script>
<script>
(function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
(i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
})(window,document,'script','https://www.google-analytics.com/analytics.js','ga');
ga('create', 'UA-101622733-1', 'auto');
ga('send', 'pageview');
</script>
</body>
</html>