-
Notifications
You must be signed in to change notification settings - Fork 0
/
search.xml
81 lines (38 loc) · 61 KB
/
search.xml
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
<?xml version="1.0" encoding="utf-8"?>
<search>
<entry>
<title>eureka client端搭建过程中无法启动</title>
<link href="/2019/06/23/%E5%85%B3%E4%BA%8E%E6%90%AD%E5%BB%BAeureka%20client%E8%BF%87%E7%A8%8B%E4%B8%AD%E6%97%A0%E6%B3%95%E5%90%AF%E5%8A%A8/"/>
<url>/2019/06/23/%E5%85%B3%E4%BA%8E%E6%90%AD%E5%BB%BAeureka%20client%E8%BF%87%E7%A8%8B%E4%B8%AD%E6%97%A0%E6%B3%95%E5%90%AF%E5%8A%A8/</url>
<content type="html"><![CDATA[<h1 id="eureka-client端搭建过程中无法启动"><a href="#eureka-client端搭建过程中无法启动" class="headerlink" title="eureka client端搭建过程中无法启动"></a>eureka client端搭建过程中无法启动</h1><p>今天在尝试搭建eureka服务注册和服务发现过程中,server端搭建启动完成之后,client端一直无法启动</p><p>启动信息如下:</p><a id="more"></a><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br><span class="line">47</span><br><span class="line">48</span><br><span class="line">49</span><br><span class="line">50</span><br><span class="line">51</span><br><span class="line">52</span><br></pre></td><td class="code"><pre><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37.266</span> INFO <span class="number">8740</span> --- [ main] c.s.c.c.e.EurekaClientApplication : No active profile set, falling back to <span class="keyword">default</span> profiles: <span class="keyword">default</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37.281</span> INFO <span class="number">8740</span> --- [ main] s.c.a.AnnotationConfigApplicationContext : Refreshing org.springframework.context.annotation.AnnotationConfigApplicationContext@<span class="number">418</span>c5a9c: startup date [Sun Jun <span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37</span> CST <span class="number">2019</span>]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@<span class="number">4</span>cc451f2</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37.707</span> INFO <span class="number">8740</span> --- [ main] o.s.cloud.context.scope.GenericScope : BeanFactory id=<span class="number">2</span>ccb9e2e-fe88-<span class="number">338</span>d-<span class="number">849</span>d-<span class="number">25</span>bf57fe2dd6</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37.721</span> INFO <span class="number">8740</span> --- [ main] f.a.AutowiredAnnotationBeanPostProcessor : JSR-<span class="number">330</span> <span class="string">'javax.inject.Inject'</span> annotation found and supported <span class="keyword">for</span> autowiring</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37.772</span> INFO <span class="number">8740</span> --- [ main] trationDelegate$BeanPostProcessorChecker : Bean <span class="string">'org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration'</span> of type [org.springframework.cloud.autoconfigure.ConfigurationPropertiesRebinderAutoConfiguration$$EnhancerBySpringCGLIB$$c6ccbb49] <span class="function">is not eligible <span class="keyword">for</span> getting processed by all <span class="title">BeanPostProcessors</span> <span class="params">(<span class="keyword">for</span> example: not eligible <span class="keyword">for</span> auto-proxying)</span></span></span><br><span class="line"><span class="function">2019-06-23 23:24:37.817 WARN 8740 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.</span></span><br><span class="line"><span class="function">2019-06-23 23:24:37.817 INFO 8740 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.</span></span><br><span class="line"><span class="function">2019-06-23 23:24:37.821 WARN 8740 --- [ main] c.n.c.sources.URLConfigurationSource : No URLs will be polled as dynamic configuration sources.</span></span><br><span class="line"><span class="function">2019-06-23 23:24:37.821 INFO 8740 --- [ main] c.n.c.sources.URLConfigurationSource : To enable URLs as dynamic configuration sources, define System property archaius.configurationSource.additionalUrls or make config.properties available on classpath.</span></span><br><span class="line"><span class="function">2019-06-23 23:24:38.819 INFO 8740 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Registering beans <span class="keyword">for</span> JMX exposure on startup</span></span><br><span class="line"><span class="function">2019-06-23 23:24:38.829 INFO 8740 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'refreshScope' has been autodetected <span class="keyword">for</span> JMX exposure</span></span><br><span class="line"><span class="function">2019-06-23 23:24:38.829 INFO 8740 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'configurationPropertiesRebinder' has been autodetected <span class="keyword">for</span> JMX exposure</span></span><br><span class="line"><span class="function">2019-06-23 23:24:38.830 INFO 8740 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Bean with name 'environmentManager' has been autodetected <span class="keyword">for</span> JMX exposure</span></span><br><span class="line"><span class="function">2019-06-23 23:24:38.833 INFO 8740 --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean 'environmentManager': registering with JMX server as MBean [org.springframework.cloud.context.environment:name</span>=environmentManager,type=EnvironmentManager]</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">38.845</span> INFO <span class="number">8740</span> --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean <span class="string">'refreshScope'</span>: registering with JMX server as MBean [org.springframework.cloud.context.scope.refresh:name=refreshScope,type=RefreshScope]</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">38.861</span> INFO <span class="number">8740</span> --- [ main] o.s.j.e.a.AnnotationMBeanExporter : Located managed bean <span class="string">'configurationPropertiesRebinder'</span>: registering with JMX server as MBean [org.springframework.cloud.context.properties:name=configurationPropertiesRebinder,context=<span class="number">418</span>c5a9c,type=ConfigurationPropertiesRebinder]</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">38.870</span> INFO <span class="number">8740</span> --- [ main] o.s.c.support.DefaultLifecycleProcessor : Starting beans in phase <span class="number">0</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">38.878</span> INFO <span class="number">8740</span> --- [ main] o.s.c.n.eureka.InstanceInfoFactory : Setting initial instance status as: STARTING</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">38.919</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Initializing Eureka in region us-east-<span class="number">1</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">39.379</span> INFO <span class="number">8740</span> --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using JSON encoding codec LegacyJacksonJson</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">39.380</span> INFO <span class="number">8740</span> --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using JSON decoding codec LegacyJacksonJson</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">39.536</span> INFO <span class="number">8740</span> --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using XML encoding codec XStreamXml</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">39.536</span> INFO <span class="number">8740</span> --- [ main] c.n.d.provider.DiscoveryJerseyProvider : Using XML decoding codec XStreamXml</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.030</span> INFO <span class="number">8740</span> --- [ main] c.n.d.s.r.aws.ConfigClusterResolver : Resolving eureka endpoints via configuration</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.280</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Disable delta property : <span class="keyword">false</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Single vip registry refresh property : <span class="keyword">null</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Force full registry fetch : <span class="keyword">false</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Application is <span class="keyword">null</span> : <span class="keyword">false</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Registered Applications size is zero : <span class="keyword">true</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Application version is -<span class="number">1</span>: <span class="keyword">true</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.281</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Getting all instance registry info from the eureka server</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.458</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : The response status is <span class="number">200</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.461</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Starting heartbeat executor: renew interval is: <span class="number">30</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.463</span> INFO <span class="number">8740</span> --- [ main] c.n.discovery.InstanceInfoReplicator : InstanceInfoReplicator onDemand update allowed rate per min is <span class="number">4</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.467</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Discovery Client initialized at timestamp <span class="number">1561303480465</span> with initial instances count: <span class="number">2</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.470</span> INFO <span class="number">8740</span> --- [ main] o.s.c.n.e.s.EurekaServiceRegistry : Registering application eureka-client with eureka with status UP</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.471</span> INFO <span class="number">8740</span> --- [ main] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=<span class="number">1561303480471</span>, current=UP, previous=STARTING]</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.472</span> INFO <span class="number">8740</span> --- [nfoReplicator-<span class="number">0</span>] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/DESKTOP-MO8NTNL:eureka-client:<span class="number">8080</span>: registering service...</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.497</span> INFO <span class="number">8740</span> --- [ main] c.s.c.c.e.EurekaClientApplication : Started EurekaClientApplication in <span class="number">5.861</span> seconds (JVM running <span class="keyword">for</span> <span class="number">7.639</span>)</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.508</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] s.c.a.AnnotationConfigApplicationContext : Closing org.springframework.context.annotation.AnnotationConfigApplicationContext@<span class="number">418</span>c5a9c: startup date [Sun Jun <span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">37</span> CST <span class="number">2019</span>]; parent: org.springframework.context.annotation.AnnotationConfigApplicationContext@<span class="number">4</span>cc451f2</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.510</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] o.s.c.n.e.s.EurekaServiceRegistry : Unregistering application eureka-client with eureka with status DOWN</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.511</span> WARN <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] com.netflix.discovery.DiscoveryClient : Saw local status change event StatusChangeEvent [timestamp=<span class="number">1561303480511</span>, current=DOWN, previous=UP]</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.521</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] o.s.c.support.DefaultLifecycleProcessor : Stopping beans in phase <span class="number">0</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.524</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] com.netflix.discovery.DiscoveryClient : Shutting down DiscoveryClient ...</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.543</span> INFO <span class="number">8740</span> --- [nfoReplicator-<span class="number">0</span>] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/DESKTOP-MO8NTNL:eureka-client:<span class="number">8080</span> - registration status: <span class="number">204</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.543</span> INFO <span class="number">8740</span> --- [nfoReplicator-<span class="number">0</span>] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/DESKTOP-MO8NTNL:eureka-client:<span class="number">8080</span>: registering service...</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.558</span> INFO <span class="number">8740</span> --- [nfoReplicator-<span class="number">0</span>] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/DESKTOP-MO8NTNL:eureka-client:<span class="number">8080</span> - registration status: <span class="number">204</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.559</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] com.netflix.discovery.DiscoveryClient : Unregistering ...</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.565</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] com.netflix.discovery.DiscoveryClient : DiscoveryClient_EUREKA-CLIENT/DESKTOP-MO8NTNL:eureka-client:<span class="number">8080</span> - deregister status: <span class="number">200</span></span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.577</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] com.netflix.discovery.DiscoveryClient : Completed shut down of DiscoveryClient</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.582</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans on shutdown</span><br><span class="line"><span class="number">2019</span>-<span class="number">06</span>-<span class="number">23</span> <span class="number">23</span>:<span class="number">24</span>:<span class="number">40.585</span> INFO <span class="number">8740</span> --- [ Thread-<span class="number">17</span>] o.s.j.e.a.AnnotationMBeanExporter : Unregistering JMX-exposed beans</span><br></pre></td></tr></table></figure><p>经过反复检查发现,是pom文件中忘了添加 spring-boot-starter-web 依赖,导致启动失败,添加依赖之后正常启动</p>]]></content>
<tags>
<tag> bugs </tag>
<tag> eureka </tag>
<tag> error </tag>
</tags>
</entry>
<entry>
<title>JVM原理</title>
<link href="/2019/05/31/JVM%E5%8E%9F%E7%90%86/"/>
<url>/2019/05/31/JVM%E5%8E%9F%E7%90%86/</url>
<content type="html"><![CDATA[<h2 id="一、JVM运行时数据区"><a href="#一、JVM运行时数据区" class="headerlink" title="一、JVM运行时数据区"></a>一、JVM运行时数据区</h2><p><img src="http://aliyunzixunbucket.oss-cn-beijing.aliyuncs.com/jpg/0585e29bac1ea1689a6ac2862067aa8a.jpg?x-oss-process=image/resize,p_100/auto-orient,1/quality,q_90/format,jpg/watermark,image_eXVuY2VzaGk=,t_100" alt="img"></p><a id="more"></a><h3 id="1-java-虚拟机栈:"><a href="#1-java-虚拟机栈:" class="headerlink" title="1.java 虚拟机栈:"></a>1.java 虚拟机栈:</h3><p>虚拟机栈描述的是Java方法执行的内存模型:每个方法被执行的时候都会同时创建一个栈帧(Stack Frame)用于存储局部变量表、操作栈、动态链接,方法出口等信息。每一个方法被调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。</p><h3 id="2-java-堆:"><a href="#2-java-堆:" class="headerlink" title="2.java 堆:"></a>2.java 堆:</h3><p>Java堆是被所有线程共享的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存。</p><h3 id="3-方法区:"><a href="#3-方法区:" class="headerlink" title="3.方法区:"></a>3.方法区:</h3><p>方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据</p><h3 id="4-运行时常量池:"><a href="#4-运行时常量池:" class="headerlink" title="4.运行时常量池:"></a>4.运行时常量池:</h3><p>运行时常量池(Runtime Constant Pool)是方法区的一部分。用于存放编译器生成的各种字面量和符号引用,这部分内容将在类加载后存放到方法区的运行时常量池中。</p><h3 id="5-程序计数器:"><a href="#5-程序计数器:" class="headerlink" title="5.程序计数器:"></a>5.程序计数器:</h3><p>程序计数器(program counter register)是一块较小的内存空间,它的作用可以看作是当前线程所执行的字节码的行号指示器。</p><h2 id="二、JVM垃圾回收算法"><a href="#二、JVM垃圾回收算法" class="headerlink" title="二、JVM垃圾回收算法"></a>二、JVM垃圾回收算法</h2><h3 id="1-标记-清除:"><a href="#1-标记-清除:" class="headerlink" title="1.标记-清除:"></a>1.标记-清除:</h3><p>最基础的收集算法,算法分为”标记“和”清除“两个阶段:首先标记出所有需要回收的对象,在标记完成后统一回收掉所有被标记的对象。缺点有:</p><p>1.效率问题,标记和清除过程的效率都不高。</p><p>2.空间问题,标记清除之后会产生大量不连续的内存碎片,空间碎片太多</p><h3 id="2-复制算法:"><a href="#2-复制算法:" class="headerlink" title="2.复制算法:"></a>2.复制算法:</h3><p>为了解决效率问题,“复制”算法出现了。它将可用内存按容量划分为大小相等的两块,每次只使用其中的一块。当这一块的内存用完了,就将还存活着的对象复制到另外一块上面,然后再把已使用过的内存空间一次清理掉。IBM的专门研究表明,新生代中的对象98%是朝生夕死的。所以将内存分为一块比较大的Eden空间和两块较小的Survivor空间,每次使用Eden和其中的一块Survivor。当回收时,将Eden和Survivor中还存活着的对象一次性的拷贝到另外一块Survivor空间上,最后清理掉Eden和刚才用过的Survivor的空间。HotSpot虚拟机默认Eden和Survivor的大小比例是8:1:1.</p><h3 id="3-标记-整理:"><a href="#3-标记-整理:" class="headerlink" title="3.标记-整理:"></a>3.标记-整理:</h3><p>标记过程与”标记-清除“算法一样,但后续步骤不是直接对可回收对象进行清理,而是让所有存活的对象都向一端移动,然后直接清理掉端边界以外的内存。</p><h3 id="4-分代收集:"><a href="#4-分代收集:" class="headerlink" title="4.分代收集:"></a>4.分代收集:</h3><p>这种算法根据对象的存活周期的不同将内存划分为几块。一般是把Java堆分为新生代和老年代,这样就可以根据各个年代的特点采用最适当的收集算法。在新生代中,每次垃圾收集时都发现有大批对象死去,只有少量存活,那就选用复制算法,只需要付出少量存活对象的复制成本就可以完成收集。而老年代中因为对象存活率高、没有额外空间对它进行分配担保,就必须使用”标记-清理“或”标记-整理“算法来进行回收。</p><h2 id="三、JVM垃圾收集器"><a href="#三、JVM垃圾收集器" class="headerlink" title="三、JVM垃圾收集器"></a>三、JVM垃圾收集器</h2><p>垃圾收集器组合</p><p><img src="http://images0.cnblogs.com/blog/587852/201411/271738454348459.png" alt="img"></p><p>上图中展示了7种不同的垃圾收集器和它们所处的位置</p><p>新生代收集器:Serial、ParNew、Parallel Scavenge</p><p>老年代收集器:Serial Old、Parallel Old、CMS</p><p>整堆:G1</p><p>两个收集器之间有连线表明他们可以搭配使用</p><h3 id="1-Serial-收集器"><a href="#1-Serial-收集器" class="headerlink" title="1.Serial 收集器"></a>1.Serial 收集器</h3><p>Serial收集器是最基本、历史最悠久的单线程收集器。但他的”单线程“的意义并不仅仅是说明它只会使用一个CPU或一条收集线程去完成垃圾收集工作,更重要的是他在进行垃圾收集时,必须暂停其他所有的工作线程(Sun将这件事情称之为”Stop The World“)直到它收集结束。</p><p><img src="http://images2018.cnblogs.com/blog/1053518/201803/1053518-20180312155929745-1493774665.png" alt="img"></p><h3 id="2-ParNew-收集器"><a href="#2-ParNew-收集器" class="headerlink" title="2.ParNew 收集器"></a>2.ParNew 收集器</h3><p>ParNew收集器其实就是Serial收集器的多线程版本,除了使用多条线程进行垃圾收集之外,其余行为包括Serial 收集器的所有控制参数、收集算法、Stop The World、对象分配规则、回收策略等都与Serial 收集器完全一样,实际上也两种收集器也共用了相当多的代码。</p><p>它作为老年代的收集器,却无法与JDK中已经存在的新生代收集器Paralle Scavenge配合工作,所以在JDK1.5中使用CMS来收集老年代的时候,新生代只能选择ParNew或Serial收集器中的一个。</p><p><img src="http://img5.imgtn.bdimg.com/it/u=1815825265,3001864538&fm=11&gp=0.jpg" alt="img"></p><h3 id="3-Parallel-Scavenge-收集器"><a href="#3-Parallel-Scavenge-收集器" class="headerlink" title="3.Parallel Scavenge 收集器"></a>3.Parallel Scavenge 收集器</h3><p>Parallel Scavenge 收集器也是一个新生代收集器,他也是使用复制算法的收集器,又是并行的多线程收集器。</p><p>Parallel Scavenge 收集器的特点使他的关注点与其他收集器不同,CMS等收集器关注点尽可能地缩短垃圾收集时用户现成的停顿时间,而Parallel Scavenge 收集器的目标则是达到一个可控制的吞吐量(Throughput)。所谓吞吐量就是CPU用于运行用户代码的时间与CPU总消耗时间的比值,及吞吐量=运行用户代码时间/(运行用户代码时间+垃圾收集时间),虚拟机总共运行了100分钟,其中垃圾收集花掉1分支,那吞吐量就是99%。</p><h3 id="4-Serial-Old-收集器"><a href="#4-Serial-Old-收集器" class="headerlink" title="4.Serial Old 收集器"></a>4.Serial Old 收集器</h3><p>Serial Old时Serial收集器的老年代版本,它同样是一个单线程收集器,使用”标记-整理“算法。这个收集器的主要意义也是被Client模式下的虚拟机使用。如果在Server模式下,它主要还有两大用途:一个实在JDK1.5及之前的版本中与Parallel Scavenge收集器搭配使用,另外一个就是作为CMS收集器的后备预案,在并发收集发生Concurrent Mode Failure的时候使用。</p><p><img src="http://images2018.cnblogs.com/blog/1053518/201803/1053518-20180312155929745-1493774665.png" alt="img"></p><h3 id="5-Parallel-Old-收集器"><a href="#5-Parallel-Old-收集器" class="headerlink" title="5.Parallel Old 收集器"></a>5.Parallel Old 收集器</h3><p>Parallel Old 是Parallel Scavenge收集器的老年代版本,使用多线程和“标记-整理“算法。这个收集器是在JDK1.6中才开始提供的,在此之前,新生代的Parallel Scavenge收集器一直处于比较尴尬的状态。原因是,如果新生代选择了Parallel Scavenge收集器,老年代除了Serial Old(PS markSweep)收集器外别无选择(Parallel Scavenge收集器无法与CMS收集器配合工作)。由于单线程的老年代Serial Old收集器在服务端应用性能上的”拖累”,即便使用了Parallel Scavenge收集器也未必能在整体引用上获得吞吐量最大化的效果,又因为老年代收集中无法充分利用服务器多CPU的处理能力,在老年代很大而且硬件比较高级的环境中,这种组合的吞吐量甚至还不一定有ParNew加CMS的组合“给力”。</p><p>直到Parallel Old收集器出现后,“吞吐量优先”收集器终于有了比较名副其实的应用组合,在注重吞吐量及CPU资源敏感的场合,都可以优先考虑Parallel Scavenge加Parallel Old收集器。</p><p><img src="http://img2.imgtn.bdimg.com/it/u=1386402115,1389397957&fm=15&gp=0.jpg" alt="img"></p><h3 id="6-CMS-收集器"><a href="#6-CMS-收集器" class="headerlink" title="6.CMS 收集器"></a>6.CMS 收集器</h3><p>CMS(Concurrent Mark Sweep)收集器是以重以获取最短回收停顿时间为目标的收集器。目前很大一部分的Java应用都集中在互联网站或B/S系统的服务端上,这类应用尤其重视服务的响应速度,希望系统停顿时间对端,以给用户带来较好的体验。CMS收集器就非常符合这类应用的需求。</p><p>从名字(包含“Mark Sweep”)上就可以看出CMS收集器是基于“标记-清除”算法实现的,他的运作过程相对于前面几种收集器来说要更复杂一些,整个过程分为4个步骤,包括:</p><p>初始标记(CMS initial mark)</p><p>并发标记(CMS concurrent mark)</p><p>重新标记(CMS remark)</p><p>并发清除(CMS concurrnet sweep)</p><p>其中初始标记、重新标记这两个步骤仍然需要“Stop The World”。初始标记仅仅只是标记一下GC Roots能直接关联到的对象,速度很快,并发标记阶段就是进行GC Roots Tracing的过程,而重新标记阶段则是为了修正并发标记期间,因用户程序继续运作而导致标记产生变动的那一部分对象的标记记录,这个阶段的停顿时间一般会比初始标记阶段稍长一些,但远比并发标记的时间短。</p><p>CMS是一款优秀的收集器,他的最主要有点在名字上已经体现出来了:并发收集、低停顿。但是还远达不到完美的成都,他有以下三个显著的缺点:</p><p>CMS收集器对CPU资源非常敏感</p><p>CMS收集器无法处理浮动垃圾(CMS并发清理阶段会产生一定的垃圾,这部分垃圾只能在下次GC的时候处理,称为浮动垃圾)</p><p>CMS是基于“标记-清除”算法实现的,这意味收集结束时会产生大量空间碎片。空间碎片过多会给大对象分配带来麻烦。CMS收集器提供了一个-XX:+UseCMSCompactAtFullCollection开关参数用于Full GC之后整理碎片,但空间碎片整理是需要停顿的。</p><p><img src="http://images2015.cnblogs.com/blog/926638/201706/926638-20170623162258054-1467865820.png" alt="img"></p><h3 id="7-G1"><a href="#7-G1" class="headerlink" title="7.G1"></a>7.G1</h3><p>G1收集器将java堆均分成大小相同的区域(region,1M-32M,最多2000个,最大支持堆内存64G)。一个或多个不连续的区域共同组成eden、survivor或old区,但大小不再固定,这为内存应用提供了极大地弹性。G1垃圾收集过程与CMS类似。G1在堆内存中并发地对所有对象进行标记,决定对象的可达性。经过全局标记,G1了解哪些区域几乎是空的,然后优先收集这些区域,这就是GarbageFirst的命名由来。G1将垃圾收集和内存整理活动专注于那些几乎全是垃圾的区域,并建立停顿预测模型来决定每次GC时回收哪些区域,以满足用户设定的停顿时间。</p><p>G1收集器是基于“标记-整理”算法实现的收集器,也就是它不会产生空间碎片,这对长时间运行的应用系统来说非常重要。</p><p>它可以非常精确的控制停顿,既能让使用者明确指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。</p>]]></content>
<tags>
<tag> jvm </tag>
</tags>
</entry>
<entry>
<title>kafka原理</title>
<link href="/2019/05/30/kafka%E5%8E%9F%E7%90%86/"/>
<url>/2019/05/30/kafka%E5%8E%9F%E7%90%86/</url>
<content type="html"><![CDATA[<h1 id="kafka原理"><a href="#kafka原理" class="headerlink" title="kafka原理"></a>kafka原理</h1><a id="more"></a><h2 id="一、为什么需要消息系统"><a href="#一、为什么需要消息系统" class="headerlink" title="一、为什么需要消息系统"></a>一、为什么需要消息系统</h2><ol><li><p>解耦:</p><p>允许你独立的拓展或修改两边的处理过程,只要确保他们遵守同样的接口约束</p></li><li><p>冗余:</p><p>消息队列把数据进行持久啊知道他们已经被完全处理,通过这一方式规避了数据丢失风险。许多消息队列所采用的“插入-获取-删除”范式中,在把一个消息从消息队列中删除之前,需要捏处理系统明确的指出该消息已经被处理完毕,从而确保你的数据被安全的保存直到你使用完毕。</p></li><li><p>扩展性:</p><p>因为消息队列解耦了你的处理过程,所以增大消息入队和处理的频率是很容易的,只要另外增加处理过程即可</p></li><li><p>灵活性&峰值处理能力:</p><p>在访问量剧增的情况下,应用仍然需要继续发挥作用,当时这样的突发流量并不常见。如果为以能处理这类峰值访问为标准来投入资源随时待命无疑是巨大的浪费。使用消息队列能够使关键组件顶住突发的访问压力,而不会因为突发的超负荷的请求而完全崩溃。</p></li><li><p>可恢复性:</p><p>系统的一部分组建失效时,不会影响到整个系统。效力对了降低了进程间的耦合度,所以即使一个处理消息的进程挂掉,加入队列中的消息仍然可以在系统恢复后被处理。</p></li><li><p>顺序保证:</p><p>在大多使用场景下,数据处理的顺序都很重要。大部分消息队列本来就是排序的,并且保证数据会按照特定的顺序来处理。(kafka保证一个Partition内的消息的有序性)</p></li><li><p>缓冲:</p><p>有助于控制和优化数据流经过系统的速度,解决生产消息和消费消息的处理速度不一致的情况。</p></li><li><p>异步通信:</p><p>很多时候,用户不想也不需要立即处理消息。消息队列提供了异步处理机制,允许用户把一个消息放入队列,但并不立即处理它。想向队列中放入多少消息就放多少,然后子啊需要的时候再去处理它们。</p></li></ol><h2 id="二、相关概念"><a href="#二、相关概念" class="headerlink" title="二、相关概念"></a>二、相关概念</h2><ol><li><p>producer:</p><p>消息生产者,发布消息到Kafka集群的终端或服务。</p></li><li><p>broker:</p><p>kafka集群中包含的服务器。</p></li><li><p>topic:</p><p>每条发布到kafka集群的消息属于的类别,即Kafka是面向topic的。</p></li><li><p>partition:</p><p>partition是物理上的概念,每个topic包含一个或多个partition。Kafka分配的单位是partition。</p></li><li><p>consumer:</p><p>从Kafka集群中消费消息的终端或服务</p></li><li><p>Consumer group:</p><p>high-level consumer API中,每个consumer都属于一个consumer group,每条消息只能被consumer group中的一个consumer消费,但可以被多个consumer group消费。</p></li><li><p>replica:</p><p>partition的副本,保障partition的高可用。</p></li><li><p>leader:</p><p>replica中的一个角色,,producer和consumer只跟leader交互。</p></li><li><p>follower:</p><p>replica中的一个角色,从leader中复制数据。</p></li><li><p>controller:</p><p>Kafka集群中的一个服务器,用来进行leader election以及各种failover。</p></li><li><p>zokeeper:</p><p>Kafka通过zookeeper来存储集群的meta信息。</p></li></ol><h2 id="三、producer发布消息"><a href="#三、producer发布消息" class="headerlink" title="三、producer发布消息"></a>三、producer发布消息</h2><h3 id="3-1-写入方式"><a href="#3-1-写入方式" class="headerlink" title="3.1 写入方式"></a>3.1 写入方式</h3><p>producer采用push模式将消息发布到broker,每条消息都被append到partition中,属于顺序写入磁盘(顺序写磁盘效率比随即写内存要高,保障kafka吞吐率)。</p><h3 id="3-2-消息路由"><a href="#3-2-消息路由" class="headerlink" title="3.2 消息路由"></a>3.2 消息路由</h3><p>producer发送消息到broker时,会根据分区算法选择将其存储到哪一个partition。其路由机制为:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br></pre></td><td class="code"><pre><span class="line">1. 指定了partition,则直接使用;</span><br><span class="line">2. 未指定partition但直到那个key,通过对key的value进行hash选出一个partition</span><br><span class="line">3. partition和key都为指定,使用轮询选出一个partition。</span><br></pre></td></tr></table></figure><p>java客服端分区源码</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br><span class="line">11</span><br><span class="line">12</span><br><span class="line">13</span><br><span class="line">14</span><br><span class="line">15</span><br><span class="line">16</span><br><span class="line">17</span><br><span class="line">18</span><br><span class="line">19</span><br><span class="line">20</span><br><span class="line">21</span><br><span class="line">22</span><br><span class="line">23</span><br><span class="line">24</span><br><span class="line">25</span><br><span class="line">26</span><br><span class="line">27</span><br><span class="line">28</span><br><span class="line">29</span><br><span class="line">30</span><br><span class="line">31</span><br><span class="line">32</span><br><span class="line">33</span><br><span class="line">34</span><br><span class="line">35</span><br><span class="line">36</span><br><span class="line">37</span><br><span class="line">38</span><br><span class="line">39</span><br><span class="line">40</span><br><span class="line">41</span><br><span class="line">42</span><br><span class="line">43</span><br><span class="line">44</span><br><span class="line">45</span><br><span class="line">46</span><br></pre></td><td class="code"><pre><span class="line"></span><br><span class="line"><span class="comment">//创建消息实例</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="title">ProducerRecord</span><span class="params">(String topic, Integer partition, Long timestamp, K key, V value)</span> </span>{</span><br><span class="line"> <span class="keyword">if</span> (topic == <span class="keyword">null</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"Topic cannot be null"</span>);</span><br><span class="line"> <span class="keyword">if</span> (timestamp != <span class="keyword">null</span> && timestamp < <span class="number">0</span>)</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(<span class="string">"Invalid timestamp "</span> + timestamp);</span><br><span class="line"> <span class="keyword">this</span>.topic = topic;</span><br><span class="line"> <span class="keyword">this</span>.partition = partition;</span><br><span class="line"> <span class="keyword">this</span>.key = key;</span><br><span class="line"> <span class="keyword">this</span>.value = value;</span><br><span class="line"> <span class="keyword">this</span>.timestamp = timestamp;</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">//计算 patition,如果指定了 patition 则直接使用,否则使用 key 计算</span></span><br><span class="line"><span class="function"><span class="keyword">private</span> <span class="keyword">int</span> <span class="title">partition</span><span class="params">(ProducerRecord<K, V> record, <span class="keyword">byte</span>[] serializedKey , <span class="keyword">byte</span>[] serializedValue, Cluster cluster)</span> </span>{</span><br><span class="line"> Integer partition = record.partition();</span><br><span class="line"> <span class="keyword">if</span> (partition != <span class="keyword">null</span>) {</span><br><span class="line"> List<PartitionInfo> partitions = cluster.partitionsForTopic(record.topic());</span><br><span class="line"> <span class="keyword">int</span> lastPartition = partitions.size() - <span class="number">1</span>;</span><br><span class="line"> <span class="keyword">if</span> (partition < <span class="number">0</span> || partition > lastPartition) {</span><br><span class="line"> <span class="keyword">throw</span> <span class="keyword">new</span> IllegalArgumentException(String.format(<span class="string">"Invalid partition given with record: %d is not in the range [0...%d]."</span>, partition, lastPartition));</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> partition;</span><br><span class="line"> }</span><br><span class="line"> <span class="keyword">return</span> <span class="keyword">this</span>.partitioner.partition(record.topic(), record.key(), serializedKey, record.value(), serializedValue, cluster);</span><br><span class="line">}</span><br><span class="line"></span><br><span class="line"><span class="comment">// 使用 key 选取 patition</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">int</span> <span class="title">partition</span><span class="params">(String topic, Object key, <span class="keyword">byte</span>[] keyBytes, Object value, <span class="keyword">byte</span>[] valueBytes, Cluster cluster)</span> </span>{</span><br><span class="line"> List<PartitionInfo> partitions = cluster.partitionsForTopic(topic);</span><br><span class="line"> <span class="keyword">int</span> numPartitions = partitions.size();</span><br><span class="line"> <span class="keyword">if</span> (keyBytes == <span class="keyword">null</span>) {</span><br><span class="line"> <span class="keyword">int</span> nextValue = counter.getAndIncrement();</span><br><span class="line"> List<PartitionInfo> availablePartitions = cluster.availablePartitionsForTopic(topic);</span><br><span class="line"> <span class="keyword">if</span> (availablePartitions.size() > <span class="number">0</span>) {</span><br><span class="line"> <span class="keyword">int</span> part = DefaultPartitioner.toPositive(nextValue) % availablePartitions.size();</span><br><span class="line"> <span class="keyword">return</span> availablePartitions.get(part).partition();</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="keyword">return</span> DefaultPartitioner.toPositive(nextValue) % numPartitions;</span><br><span class="line"> }</span><br><span class="line"> } <span class="keyword">else</span> {</span><br><span class="line"> <span class="comment">//对 keyBytes 进行 hash 选出一个 patition</span></span><br><span class="line"> <span class="keyword">return</span> DefaultPartitioner.toPositive(Utils.murmur2(keyBytes)) % numPartitions;</span><br><span class="line"> }</span><br><span class="line">}</span><br></pre></td></tr></table></figure><h3 id="3-3-写入流程"><a href="#3-3-写入流程" class="headerlink" title="3.3 写入流程"></a>3.3 写入流程</h3><p><img src="http://images2015.cnblogs.com/blog/897247/201610/897247-20161012161552718-1963426687.png" alt="img"></p><p>流程总结:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1. producer 先从 zookeeper 的 "/brokers/.../state" 节点找到该 partition 的 leader</span><br><span class="line">2. producer 将消息发送给该 leader</span><br><span class="line">3. leader 将消息写入本地 log</span><br><span class="line">4. followers 从 leader pull 消息,写入本地 log 后 leader 发送 ACK</span><br><span class="line">5. leader 收到所有 ISR 中的 replica 的 ACK 后,增加 HW(high watermark,最后 commit 的 offset) 并向 producer 发送 ACK</span><br></pre></td></tr></table></figure><h3 id="3-4-发送消息"><a href="#3-4-发送消息" class="headerlink" title="3.4 发送消息"></a>3.4 发送消息</h3><p>发送消息主要有三种方式:</p><ul><li><p>fire-and-forget(发送并忘记):</p><p>不关注消息是否成功到达,大部分情况下没消息会成功送达至broker。但是还是会存在消息丢失的情况</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">ProducerRecord<String, String> record = <span class="keyword">new</span> ProducerRecord<String, String>(<span class="string">"CustomerCountry"</span>,</span><br><span class="line"><span class="string">"Precision Products"</span>, <span class="string">"France"</span>);</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line">producer.send(record);</span><br><span class="line">} <span class="keyword">catch</span> (Exception e) {</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>Synchronous send(同步发送):</p><p>调用send方法后返回一个Future对象,在调用get()方法会等待直到结果返回,根据返回的结果可以判断是都发送成功</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br></pre></td><td class="code"><pre><span class="line">ProducerRecord<String, String> record = <span class="keyword">new</span> ProducerRecord<String, String>(<span class="string">"CustomerCountry"</span>,</span><br><span class="line"><span class="string">"Precision Products"</span>, <span class="string">"France"</span>);</span><br><span class="line"><span class="keyword">try</span> {</span><br><span class="line">producer.send(record).get();</span><br><span class="line">} <span class="keyword">catch</span> (Exception e) {</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br></pre></td></tr></table></figure></li></ul><ul><li><p>Aysnchronous send(异步发送):</p><p>我们调用send()方法,并指定一个回调函数,服务器在返回响应时调用该函数。</p><figure class="highlight java"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br><span class="line">6</span><br><span class="line">7</span><br><span class="line">8</span><br><span class="line">9</span><br><span class="line">10</span><br></pre></td><td class="code"><pre><span class="line"><span class="class"><span class="keyword">class</span> <span class="title">DemoProducerCallback</span> <span class="keyword">implements</span> <span class="title">Callback</span> </span>{</span><br><span class="line"><span class="meta">@Override</span></span><br><span class="line"><span class="function"><span class="keyword">public</span> <span class="keyword">void</span> <span class="title">onCompletion</span><span class="params">(RecordMetadata recordMetadata, Exception e)</span> </span>{</span><br><span class="line"><span class="keyword">if</span> (e != <span class="keyword">null</span>) {</span><br><span class="line">e.printStackTrace();</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line">}</span><br><span class="line"> </span><br><span class="line">producer.send(record, <span class="keyword">new</span> DemoProducerCallback());</span><br></pre></td></tr></table></figure><p>要使用callback函数,先要实现Callback接口,该接口只有一个onCompletion方法。如果发送异常,onCompletion的参数Exception e会为非空</p></li></ul><h2 id="四、broker-保存消息"><a href="#四、broker-保存消息" class="headerlink" title="四、broker 保存消息"></a>四、broker 保存消息</h2><h3 id="4-1-存储方式"><a href="#4-1-存储方式" class="headerlink" title="4.1 存储方式"></a>4.1 存储方式</h3><p>物理上把topic分成一个或多个partition(对应server.properties中的num.partition=3 配置),每个partiton物理上对应一个文件下(该文件夹存储该partition的所有消息和索引文件)。</p><h3 id="4-2-存储策略"><a href="#4-2-存储策略" class="headerlink" title="4.2 存储策略"></a>4.2 存储策略</h3><p>无论消息是否被消费,kafka都会保留所有消息。有两种策略可以删除旧数据:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1. 基于时间:log.retention.hours=168</span><br><span class="line">2. 基于大小:log.retention.bytes=1073741824</span><br></pre></td></tr></table></figure><p>kafka读取特定消息的时间复杂度为O(1),即与文件大小无关,所以这里删除过期文件与提高Kafka性能无关。</p><h3 id="4-3-topic-创建与删除"><a href="#4-3-topic-创建与删除" class="headerlink" title="4.3 topic 创建与删除"></a>4.3 topic 创建与删除</h3><h4 id="4-3-1-topic创建"><a href="#4-3-1-topic创建" class="headerlink" title="4.3.1 topic创建"></a>4.3.1 topic创建</h4><p>创建图例:</p><p><img src="https://images2015.cnblogs.com/blog/897247/201610/897247-20161012161552718-1963426687.png" alt="img"></p><p>流程说明:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br><span class="line">3</span><br><span class="line">4</span><br><span class="line">5</span><br></pre></td><td class="code"><pre><span class="line">1. controller 在 ZooKeeper 的 /brokers/topics 节点上注册 watcher,当 topic 被创建,则 controller 会通过 watch 得到该 topic 的 partition/replica 分配。</span><br><span class="line">2. controller从 /brokers/ids 读取当前所有可用的 broker 列表,对于 set_p 中的每一个 partition:</span><br><span class="line">2.1 从分配给该 partition 的所有 replica(称为AR)中任选一个可用的 broker 作为新的 leader,并将AR设置为新的 ISR</span><br><span class="line">2.2 将新的 leader 和 ISR 写入 /brokers/topics/[topic]/partitions/[partition]/state</span><br><span class="line">3. controller 通过 RPC 向相关的 broker 发送 LeaderAndISRRequest。</span><br></pre></td></tr></table></figure><h4 id="4-3-2-topic删除"><a href="#4-3-2-topic删除" class="headerlink" title="4.3.2 topic删除"></a>4.3.2 topic删除</h4><p>删除图例:</p><p><img src="https://images2015.cnblogs.com/blog/897247/201610/897247-20161012162436140-850153613.png" alt="img"></p><p>流程说明:</p><figure class="highlight plain"><table><tr><td class="gutter"><pre><span class="line">1</span><br><span class="line">2</span><br></pre></td><td class="code"><pre><span class="line">1. controller 在 zooKeeper 的 /brokers/topics 节点上注册 watcher,当 topic 被删除,则 controller 会通过 watch 得到该 topic 的 partition/replica 分配。</span><br><span class="line">2. 若 delete.topic.enable=false,结束;否则 controller 注册在 /admin/delete_topics 上的 watch 被 fire,controller 通过回调向对应的 broker 发送 StopReplicaRequest。</span><br></pre></td></tr></table></figure>]]></content>
<tags>
<tag> kafka </tag>
</tags>
</entry>
<entry>
<title>Hello World</title>
<link href="/2019/05/13/hello-world/"/>
<url>/2019/05/13/hello-world/</url>
<content type="html"><![CDATA[<p>Welcome to <a href="https://hexo.io/" target="_blank" rel="noopener">Hexo</a>! This is your very first post. Check <a href="https://hexo.io/docs/" target="_blank" rel="noopener">documentation</a> for more info. If you get any problems when using Hexo, you can find the answer in <a href="https://hexo.io/docs/troubleshooting.html" target="_blank" rel="noopener">troubleshooting</a> or you can ask me on <a href="https://github.com/hexojs/hexo/issues" target="_blank" rel="noopener">GitHub</a>.</p><a id="more"></a><h2 id="Quick-Start"><a href="#Quick-Start" class="headerlink" title="Quick Start"></a>Quick Start</h2><h3 id="Create-a-new-post"><a href="#Create-a-new-post" class="headerlink" title="Create a new post"></a>Create a new post</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo new <span class="string">"My New Post"</span></span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/writing.html" target="_blank" rel="noopener">Writing</a></p><h3 id="Run-server"><a href="#Run-server" class="headerlink" title="Run server"></a>Run server</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo server</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/server.html" target="_blank" rel="noopener">Server</a></p><h3 id="Generate-static-files"><a href="#Generate-static-files" class="headerlink" title="Generate static files"></a>Generate static files</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo generate</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/generating.html" target="_blank" rel="noopener">Generating</a></p><h3 id="Deploy-to-remote-sites"><a href="#Deploy-to-remote-sites" class="headerlink" title="Deploy to remote sites"></a>Deploy to remote sites</h3><figure class="highlight bash"><table><tr><td class="gutter"><pre><span class="line">1</span><br></pre></td><td class="code"><pre><span class="line">$ hexo deploy</span><br></pre></td></tr></table></figure><p>More info: <a href="https://hexo.io/docs/deployment.html" target="_blank" rel="noopener">Deployment</a></p>]]></content>
</entry>
</search>