你的位置:首页 > ASP.net教程

[ASP.net教程]第二章 微服务架构搭建 + 服务启动注册


一、首先编写微服务基础项目framework

1、pom.

 1 <??> 2 <project ="http://maven.apache.org/POM/4.0.0" ="http://www.w3.org/2001/ 3   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4  5   <modelVersion>4.0.0</modelVersion> 6    7   <parent> 8     <groupId>org.springframework.boot</groupId> 9     <artifactId>spring-boot-starter-parent</artifactId>10     <version>1.3.0.RELEASE</version>11   </parent>12 13   <groupId>com.microservice</groupId>14   <artifactId>framework</artifactId>15   <version>1.0-SNAPSHOT</version>16   <packaging>jar</packaging>17 18   <properties>19     <java.version>1.8</java.version><!-- 官方推荐 -->20   </properties>21 22   <!-- 引入实际依赖 -->23   <dependencies>24     <dependency>25       <groupId>org.springframework.boot</groupId>26       <artifactId>spring-boot-starter-web</artifactId>27     </dependency>28     <!-- consul-client -->29     <dependency>30       <groupId>com.orbitz.consul</groupId>31       <artifactId>consul-client</artifactId>32       <version>0.10.0</version>33     </dependency>34     <!-- consul需要的包 -->35     <dependency>36       <groupId>org.glassfish.jersey.core</groupId>37       <artifactId>jersey-client</artifactId>38       <version>2.22.2</version>39     </dependency>40     <dependency>41       <groupId>com.alibaba</groupId>42       <artifactId>fastjson</artifactId>43       <version>1.1.15</version>44     </dependency>45     <dependency>46       <groupId>org.springframework.boot</groupId>47       <artifactId>spring-boot-starter-actuator</artifactId>48     </dependency>49     <dependency>50       <groupId>org.projectlombok</groupId>51       <artifactId>lombok</artifactId>52       <version>1.16.8</version>53       <scope>provided</scope>54     </dependency>55   </dependencies>56 57   <build>58     <plugins>59       <plugin>60         <groupId>org.springframework.boot</groupId>61         <artifactId>spring-boot-maven-plugin</artifactId>62       </plugin>63     </plugins>64   </build>65 </project>

View Code

说明:

  • 上边的<packaging>jar</packaging>可以去掉。因为spring-boot-maven-plugin会打jar包的
  • 引入spring-boot-starter-actuator是为了注册服务的时候可以直接使用"http://localhost:8080/health"进行健康检查。见第二十章 springboot + consul

2、com.microservice.framework.MySpringAplication

 1 package com.microservice.framework; 2  3 import org.springframework.boot.SpringApplication; 4 import org.springframework.boot.autoconfigure.SpringBootApplication; 5  6 import com.microservice.framework.consul.ConsulRegisterListener; 7  8 /** 9  * 注意:@SpringBootApplication该注解必须在SpringApplication.run()所在的类上10  *11 */12 @SpringBootApplication13 public class MySpringAplication {14 15   public void run(String[] args) {16     SpringApplication sa = new SpringApplication(MySpringAplication.class);17     sa.addListeners(new ConsulRegisterListener());18     sa.run(args);19   }20   21   public static void main(String[] args) {22   }23 }

View Code

注意:这里的main方法声明是要有的(否则无法install为jar)。

3、com.microservice.framework.consul.ConsulRegisterListener

 1 package com.microservice.framework.consul; 2  3 import java.net.MalformedURLException; 4 import java.net.URI; 5  6 import org.springframework.context.ApplicationListener; 7 import org.springframework.context.event.ContextRefreshedEvent; 8  9 import com.orbitz.consul.AgentClient;10 import com.orbitz.consul.Consul;11 12 /**13  * 监听contextrefresh事件14 */15 public class ConsulRegisterListener implements ApplicationListener<ContextRefreshedEvent> {16 17   @Override18   public void onApplicationEvent(ContextRefreshedEvent event) {19     Consul consul = event.getApplicationContext().getBean(Consul.class);20     ConsulProperties prop = event.getApplicationContext().getBean(ConsulProperties.class);21 22     AgentClient agentClient = consul.agentClient();23     try {24       agentClient.register(prop.getServicePort(), 25                  URI.create(prop.getHealthUrl()).toURL(),26                  prop.getHealthInterval(), 27                  prop.getServicename(), 28                 prop.getServicename(), // serviceId:29                  prop.getServiceTag());30     } catch (MalformedURLException e) {31       e.printStackTrace();32     }33   }34 35 }

View Code

注意:这个代码是关键,后边会讲改代码的作用。

其中,ConsulProperties和Consul我们需要在代码中构建成Bean(如下变4和5),之后才能从容器中取出来,否则为null。

4、com.microservice.framework.consul.ConsulProperties

 1 package com.microservice.framework.consul; 2  3 import org.springframework.beans.factory.annotation.Value; 4 import org.springframework.stereotype.Component; 5  6 import lombok.Getter; 7 import lombok.Setter; 8  9 @Component10 @Getter @Setter11 public class ConsulProperties {12 13   @Value("${service.name}")14   private String servicename;15   @Value("${service.port:8080}")16   private int servicePort;17   @Value("${service.tag:dev}")18   private String serviceTag;19 //  @Value("${serviceIp:localhost}")20 //  private String serviceIp;21   22   @Value("${health.url}")23   private String healthUrl;24   @Value("${health.interval:10}")25   private int healthInterval;26   27 }

View Code

注意:

  • 这里使用lombok简化了pojo
  • @value注解中可以指定默认值,查看上边":"后边的值就是

5、com.microservice.framework.consul.ConsulConfig

 1 package com.microservice.framework.consul; 2  3 import org.springframework.context.annotation.Bean; 4 import org.springframework.context.annotation.Configuration; 5  6 import com.orbitz.consul.Consul; 7  8 @Configuration 9 public class ConsulConfig {10 11   @Bean12   public Consul consul(){13     return Consul.builder().build();14   }15 }

View Code

编写完上述代码后,执行"mvn clean install",如果成功的话,此时"framework-1.0-SNAPSHOT.jar"这个jar就会装载到本地的.m2/repository/com/microservice/framework/q.0-SNAPSHOT中了(mac中.m2默认在~下)

 

二、开发第一个微服务myserviceA

像上边所示,我们创建了client和server。

  • server:用于实现具体逻辑
  • client:用于封装server接口(通常就是server模块的controller中的各个url),提供给其他service或gateway甚至是app使用

1、myserviceA

pom.

 1 <??> 2 <project ="http://maven.apache.org/POM/4.0.0" ="http://www.w3.org/2001/ 3   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4  5   <modelVersion>4.0.0</modelVersion> 6  7   <parent> 8     <groupId>org.springframework.boot</groupId> 9     <artifactId>spring-boot-starter-parent</artifactId>10     <version>1.3.0.RELEASE</version>11   </parent>12 13   <groupId>com.microservice</groupId>14   <artifactId>myserviceA</artifactId>15   <version>1.0-SNAPSHOT</version>16   <packaging>pom</packaging>17 18   <properties>19     <java.version>1.8</java.version><!-- 官方推荐 -->20   </properties>21 22   <modules>23     <module>server</module>24     <module>client</module>25   </modules>26 27   <!-- 引入实际依赖 -->28   <dependencies>29     <dependency>30       <groupId>org.springframework.boot</groupId>31       <artifactId>spring-boot-starter-web</artifactId>32     </dependency>33   </dependencies>34 </project>

View Code

2、myserviceA-server

2.1、pom.

 1 <??> 2 <project ="http://maven.apache.org/POM/4.0.0" ="http://www.w3.org/2001/ 3   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4  5   <modelVersion>4.0.0</modelVersion> 6    7   <parent> 8     <groupId>com.microservice</groupId> 9     <artifactId>myserviceA</artifactId>10     <version>1.0-SNAPSHOT</version>11   </parent>12 13   <artifactId>myserviceA-server</artifactId>14 15   <!-- 引入实际依赖 -->16   <dependencies>17     <dependency>18       <groupId>com.microservice</groupId>19       <artifactId>framework</artifactId>20       <version>1.0-SNAPSHOT</version>21     </dependency>22     <dependency>23       <groupId>com.alibaba</groupId>24       <artifactId>fastjson</artifactId>25       <version>1.1.15</version>26     </dependency>27   </dependencies>28 29   <build>30     <plugins>31       <plugin>32         <groupId>org.springframework.boot</groupId>33         <artifactId>spring-boot-maven-plugin</artifactId>34       </plugin>35     </plugins>36   </build>37 </project>

View Code

2.2、application.properties

1 service.name=myserviceA2 service.port=80803 service.tag=dev4 health.url=http://localhost:8080/health5 health.interval=10

View Code

说明:

  • service.name(这是一个service在注册中心的唯一标识)
  • service.port
  • service.tag(该值用于在注册中心的配置管理,dev环境下使用dev的配置,prod下使用prod的配置,配置管理通常使用KV来实现的,tag用于构建Key)
  • health.url(健康检查的url)
  • health.interval(每隔10s ping一次health.url,进行健康检查)

2.3、com.microservice.myserviceA.MyServiceAApplication

 1 package com.microservice.myserviceA; 2  3 import org.springframework.boot.autoconfigure.SpringBootApplication; 4  5 import com.microservice.framework.MySpringAplication; 6  7 @SpringBootApplication 8 public class MyServiceAApplication { 9 10   public static void main(String[] args) {11     MySpringAplication mySpringAplication = new MySpringAplication();12     mySpringAplication.run(args);13   }14 }

View Code

说明:这里调用了framework中的MySpringAplication的run(),该run()首先初始化了SpringApplication实例,之后为该实例添加ConsulRegisterListener实例,最后再执行SpringApplication的run()。

ConsulRegisterListener的执行时机见附4 springboot源码解析-run(),简言之,就是

  • run()方法会先构建容器ApplicationContext,之后将各个BeanDefinition装入该容器,最后刷新容器,这时候执行ConsulRegisterListener中的onApplication方法,用于注册service到consul。

3、myserviceA-client

pom.

 1 <??> 2 <project ="http://maven.apache.org/POM/4.0.0" ="http://www.w3.org/2001/ 3   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd"> 4    5   <modelVersion>4.0.0</modelVersion> 6    7   <parent> 8     <groupId>com.microservice</groupId> 9     <artifactId>myserviceA</artifactId>10     <version>1.0-SNAPSHOT</version>11   </parent>12 13   <artifactId>myserviceA-client</artifactId>14 15   <build>16     <plugins>17       <plugin>18         <groupId>org.springframework.boot</groupId>19         <artifactId>spring-boot-maven-plugin</artifactId>20       </plugin>21     </plugins>22   </build>23 </project>

View Code

该client以后在需要用到的时候完成。

 

测试:启动consul,开发环境下,直接使用"consul agent -dev"快速启动,查看consul UI,如下:

 

启动"myserviceA-server",启动完成后,查看consul UI,如下:

表示注册成功,我们还可以查看myserviceA的健康检查URL,如下:

 

以上就完成了基本微服务架构的搭建与服务启动时自动注册!