基于Spring Boot 2.0 的微服务实战项目
前言
这里会用到Spring Cloud Netflix,该项目是Spring Cloud的子项目之一,主要内容是对Netflix公司一系列开源产品的包装,它为Spring Boot应用提供了自配置的Netflix OSS整合。通过一些简单的注解,开发者就可以快速的在应用中配置一下常用模块并构建庞大的分布式系统。它主要提供的模块包括Eureka,Hystrix,Zuul,Ribbon等。这里的核心内容是服务发现模块:Eureka 创建服务注册中心。
- 创建基于Web的Maven项目(Spring Cloud)
- 创建服务注册中心。在Spring Cloud项目中创建Spring Boot项目(Spring Boot):
勾选Cloud Discovery–>Eureka server。以方便导包
- 编写Spring Boot项目
3.1查看pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hand</groupId>
<artifactId>springclouddemo</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>springclouddemo</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
- 在启动类上加上注解 如下
通过@EnableEurekaServer注解启动一个服务注册中心提供给其他应用进行对话。这一步非常的简单,只需要在一个普通的Spring Boot应用中添加这个注解就能开启此功能,比如下面的例子:
@SpringBootApplication
@EnableEurekaServer
public class SpringclouddemoApplication {
public static void main(String[] args) {
SpringApplication.run(SpringclouddemoApplication.class, args);
}
}
- 修改application.yml文件(也可以使用properties)
yml文件的好处,天然的树状结构,一目了然
yaml配置如下:
---
#端口号
server:
port: 8760
eureka:
instance:
hostname: localhost
client:
# eureka.client.registerWithEureka :表示是否将自己注册到Eureka Server,默认为true。
# 由于当前这个应用就是Eureka Server,故而设为false
register-with-eureka: false
# eureka.client.fetchRegistry :表示是否从Eureka Server获取注册信息,默认为true。因为这是一个单点的Eureka Server,
# 不需要同步其他的Eureka Server节点的数据,故而设为false。
fetch-registry: false
service-url:
# eureka.client.serviceUrl.defaultZone :设置与Eureka Server交互的地址,
#查询服务和注册服务都需要依赖这个地址。默认是
defaultZone: http://${eureka.instance.hostname}:${server.port}/eureka/
properties配置如下:
#端口号
server.port=8760
eureka.instance.hostname=localhost
#eureka.client.register-with-eureka:表示是否将自己注册到Eureka Server,默认为true
# 由于当前这个应用就是Eureka Server,故而设为false
eureka.client.register-with-eureka=false
#eureka.client.fetch-registry:表示是否从Eureka Server获取注册信息,默认为true
#因为这是一个单点的Eureka Server,不需要同步其他的Eureka Server节点的数据,故而设为false
eureka.client.fetch-registry=false
#eureka.client.service-url.defaultZone:设置与Eureka Server交互的地址,
#查询服务和注册服务都需要依赖这个地址,默认是:
eureka.client.service-url.defaultZone=//${eureka.instance.hostname}:${server.port}/eureka/
- 启动项目后访问
http://localhost:8760 可以看到下面的页面,其中还没有发现任何服务:
- 搭建服务端(生产者)
创建springBoot项目同上 查看pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hand</groupId>
<artifactId>producer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>producer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
- 修改application.yml文件
注:端口不能与上面的相同。这里的服务name:service-hi 可以根据自己情况定义。
yaml配置如下:
server:
port: 8762
eureka:
client:
service-url:
defaultZone: http://localhost:8760/eureka/
spring:
application:
name: service-producer
properties配置如下:
server.port=8762
eureka.client.service-url.defaultZone:http://localhost:8760/eureka/
spring.application.name=service-producer
- 编写启动类
@SpringBootApplication
@EnableEurekaClient
@RestController
public class SpringcloudproducerApplication {
public static void main(String[] args) {
SpringApplication.run(SpringcloudproducerApplication.class, args);
}
@Value("${server.port}")
String port;
private int number = 0;
@ResponseBody
@RequestMapping("hi")
public Map<String, Object> home(@RequestParam String name){
Map<String,Object> map = new HashMap<String,Object>();
Goods goods = new Goods();
goods.setGoodName("面包");
goods.setGoodPrice("10元");
goods.setGoodPlace("北京市");
goods.setGoodType("食物");
map.put("name",name);
map.put("date",new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(new Date()));
map.put("shop",goods);
map.put("port",port);
map.put("ClickNumber",++number);
//return "hi " + name + ",i am from port:"+port;
return map;
}
}
创建了一个实体类(可自行修改)
只截取一部分,其他get,set方法不做展示
/**
* 商品信息
*/
public class Goods {
/**
* 商品名称
*/
private String goodName;
/**
* 商品价格
*/
private String goodPrice;
/**
* 商品产地
*/
private String goodPlace;
/**
* 商品种类
*/
private String goodType;
运行服务
http://localhost:8762/hi?name=hrh@hand-china.com
然后查看http://localhost:8760 可以看到,我们定义的服务被注册了。如下图所示:
10. 创建消费者
10.1 创建消费者modul,流程如上述工程创建流程。
10.2 查看pom.xml文件
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.1.3.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.hand</groupId>
<artifactId>customer</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>customer</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Greenwich.RELEASE</spring-cloud.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-netflix-eureka-server</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
</dependencies>
</dependencyManagement>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
<repositories>
<repository>
<id>spring-milestones</id>
<name>Spring Milestones</name>
<url>https://repo.spring.io/milestone</url>
</repository>
</repositories>
</project>
- yml配置
---
server:
port: 8763
eureka:
client:
service-url:
defaultZone: http://localhost:8760/eureka/
spring:
application:
name: service-customer
feign:
hystrix:
enabled : true
server.port=8763
eureka.client.service-url.defaultZone=http://localhost:8760/eureka/
spring.application.name=service-customer
feign.hystrix.enabled=true
- 编写启动类
@EnableDiscoveryClient表明标注类是消费者,加入restTemplate以消费相关的服务
@SpringBootApplication
@EnableDiscoveryClient
public class CustomerApplication {
public static void main(String[] args) {
SpringApplication.run(CustomerApplication.class, args);
}
@Bean
@LoadBalanced
RestTemplate restTemplate() {
return new RestTemplate();
}
}
13 .创建service和controller
13.1 service层
@Service
public class HelloService {
@Autowired
RestTemplate restTemplate;
/**
* @param name
* @return
*/
public Map<String,Object> hiService(String name){
return restTemplate.getForObject("http://SERVICE-PRODUCER/hi?name=" + name, Map.class);
}
}
13.2 controller层
@RestController
public class HelloController {
@Autowired
HelloService helloService;
@ResponseBody
@RequestMapping(value = "/hi")
public Map<String,Object> hi(@RequestParam String name){
return helloService.hiService(name);
}
}
再次查看服务
在浏览器中输入http://localhost:8763/hi?name=admin