item service项目
01.使用springboot创建项目
02.选择依懒项在这里插入代码片
spring web
03.添加sp01-commons依赖
在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 https://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.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp02-itemservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp02-itemservice</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>sp01-commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
04.修改application.yml
ItemServiceImpl
spring:
application:
name: item-service
#spring的内置tomcat端口号
server:
port: 8001
05.创建接口实现类和controller类
package cn.tedu.sp02.service;
import java.util.ArrayList;
import java.util.List;
import org.springframework.stereotype.Service;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.service.ItemService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class ItemServiceImpl implements ItemService {
@Override
public List<Item> getItems(String orderId) {
ArrayList<Item> list = new ArrayList<Item>();
list.add(new Item(1, "商品 1",1));
list.add(new Item(2, "商品 2",2));
list.add(new Item(3, "商品 3",3));
list.add(new Item(4, "商品 4",4));
list.add(new Item(5, "商品 5",5));
return list;
}
@Override
public void decreaseNumbers(List<Item> list) {
for(Item item : list) {
log.info("减少库存 - "+item);
}
}
}
ItemController
package cn.tedu.sp02.item.controller;
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.service.ItemService;
import cn.tedu.web.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class ItemController {
@Autowired
private ItemService itemService;
@Value("${server.port}")
private int port;
@GetMapping("/{orderId}")
public JsonResult<List<Item>> getItems(@PathVariable String orderId) {
log.info("server.port="+port+", orderId="+orderId);
List<Item> items = itemService.getItems(orderId);
return JsonResult.ok(items).msg("port="+port);
}
@PostMapping("/decreaseNumber")
public JsonResult decreaseNumber(@RequestBody List<Item> items) {
itemService.decreaseNumbers(items);
return JsonResult.ok();
}
}
注:Spring MVC接受参数的几个注解,controller类中使用的参数注解
注解@GetMapping()=@RequstMapping+前端提交的方法是get
user service 用户服务
01.新建spring boot起步项目
02.选择依赖项
03.pom.xml
要添加sp01-commons项目依赖
<?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 https://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.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp03-userservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp03-userservice</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>sp01-commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
04.修改application.yml文件
#其中 sp.user-service.users 属性为自定义属性,提供用于测试的用户数据
sp:
user-service:
users: "[{\"id\":7, \"username\":\"abc\",\"password\":\"123\"},{\"id\":8, \"username\":\"def\",\"password\":\"456\"},{\"id\":9, \"username\":\"ghi\",\"password\":\"789\"}]"
spring:
application:
name: user-service
server:
port: 8101
05.接口实现类和controller类
UserServiceImpl
package cn.tedu.sp03.user.service;
import java.util.List;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import com.fasterxml.jackson.core.type.TypeReference;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.service.UserService;
import cn.tedu.web.util.JsonUtil;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class UserServiceImpl implements UserService {
@Value("${sp.user-service.users}")
private String userJson;
@Override
public User getUser(Integer id) {
log.info("users json string : "+userJson);
List<User> list = JsonUtil.from(userJson, new TypeReference<List<User>>() {});
for (User u : list) {
if (u.getId().equals(id)) {
return u;
}
}
return new User(id, "name-"+id, "pwd-"+id);
}
@Override
public void addScore(Integer id, Integer score) {
// 这里增加积分
log.info("user "+id+" - 增加积分 "+score);
}
}
UserController
package cn.tedu.sp03.user.controller;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.service.UserService;
import cn.tedu.web.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{userId}")
public JsonResult<User> getUser(@PathVariable Integer userId) {
log.info("get user, userId="+userId);
User u = userService.getUser(userId);
return JsonResult.ok(u);
}
@GetMapping("/{userId}/score")
public JsonResult addScore(
@PathVariable Integer userId, Integer score) {
userService.addScore(userId, score);
return JsonResult.ok();
}
}
order service 订单服务
01.新建spring boot起步项目
02.pom文件,要添加sp01-commons项目依赖
<?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 https://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.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp04-orderservice</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp04-orderservice</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>cn.tedu</groupId>
<artifactId>sp01-commons</artifactId>
<version>0.0.1-SNAPSHOT</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
03.application.yml
spring:
application:
name: order-service
server:
port: 8201
04.接口实现类和controller类
OrderServiceImpl
package cn.tedu.sp04.order.service;
import org.springframework.stereotype.Service;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.service.OrderService;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@Service
public class OrderServiceImpl implements OrderService {
@Override
public Order getOrder(String orderId) {
//TODO: 调用user-service获取用户信息
//TODO: 调用item-service获取商品信息
Order order = new Order();
order.setId(orderId);
return order;
}
@Override
public void addOrder(Order order) {
//TODO: 调用item-service减少商品库存
//TODO: 调用user-service增加用户积分
log.info("保存订单:"+order);
}
}
OrderController
package cn.tedu.sp04.order.controller;
import java.util.Arrays;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RestController;
import cn.tedu.sp01.pojo.Item;
import cn.tedu.sp01.pojo.Order;
import cn.tedu.sp01.pojo.User;
import cn.tedu.sp01.service.OrderService;
import cn.tedu.web.util.JsonResult;
import lombok.extern.slf4j.Slf4j;
@Slf4j
@RestController
public class OrderController {
@Autowired
private OrderService orderService;
@GetMapping("/{orderId}")
public JsonResult<Order> getOrder(@PathVariable String orderId) {
log.info("get order, id="+orderId);
Order order = orderService.getOrder(orderId);
return JsonResult.ok(order);
}
@GetMapping("/")
public JsonResult addOrder() {
//模拟post提交的数据
Order order = new Order();
order.setId("123abc");
order.setUser(new User(7,null,null));
order.setItems(Arrays.asList(new Item[] {
new Item(1,"aaa",2),
new Item(2,"bbb",1),
new Item(3,"ccc",3),
new Item(4,"ddd",1),
new Item(5,"eee",5),
}));
orderService.addOrder(order);
return JsonResult.ok();
}
}
有一个问题,如果存在多个item service (每一个item service 分别在一台不同的服务器中),有一个item service服务宕机的话,如何去调用另一个item service?是不是需要将每一个item service的ip地址都存储在其他调用这个service服务的service中?
使用注册中心,springcloud的注册中心是Eureka。
Eureka和zookeeper有什么区别
Eureka的几个功能:
启动Eureka项目
1.创建eureka项目
用
2.添加eureka server依赖,配置依赖 pom.xml
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 https://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.3.1.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>cn.tedu</groupId>
<artifactId>sp05-eureka</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>sp05-eureka</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
<spring-cloud.version>Hoxton.SR12</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>
<exclusions>
<exclusion>
<groupId>org.junit.vintage</groupId>
<artifactId>junit-vintage-engine</artifactId>
</exclusion>
</exclusions>
</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>
</project>
3.配置 application.yml
spring:
application:
name: eureka-server
server:
port: 2001
eureka:
server:
enable-self-preservation: false
instance:
hostname: eureka1
client:
register-with-eureka: false
fetch-registry: false
eureka 集群服务器之间,通过 hostname 来区分
eureka.server.enable-self-preservation
eureka 的自我保护状态:心跳失败的比例,在15分钟内是否超过85%,如果出现了超过的情况,Eureka Server会将当前的实例注册信息保护起来,同时提示一个警告,一旦进入保护模式,Eureka Server将会尝试保护其服务注册表中的信息,不再删除服务注册表中的数据。也就是不会注销任何微服务
eureka.client.register-with-eureka=false
不向自身注册
eureka.client.fetch-registry=false
不从自身拉取注册信息
eureka.instance.lease-expiration-duration-in-seconds
最后一次心跳后,间隔多久认定微服务不可用,默认90
4.主程序启用 eureka 服务器
添加 @EnableEurekaServer,在主启动类中用注解@EnableEurekaServer
package cn.tedu.sp05;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
@EnableEurekaServer
@SpringBootApplication
public class Sp05EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(Sp05EurekaApplication.class, args);
}
}
5.修改 hosts 文件,添加 eureka 域名映射
在C:\Windows\System32\drivers\etc\hosts中添加内容,跟Nginx一样
127.0.0.1 eureka1
127.0.0.1 eureka2
6.启动,并访问测试
http://eureka1:2001
service provider 服务提供者
修改 item-service、user-service、order-service,把微服务注册到 eureka 服务器
1.pom.xml 添加eureka依赖
pom.xml 添加 eureka 客户端依赖
上面的操作会在pom.xml中添加以下依赖
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>
spring-cloud-starter-netflix-eureka-client
</artifactId>
</dependency>
2.application.yml 添加eureka注册配置
eureka:
client:
service-url:
defaultZone: http://eureka1:2001/eureka
defaultZone,默认位置,可以修改为具体地理位置,比如:beiJing, shangHai, shenZhen 等,表示 eureka 服务器的部署位置, 需要云服务器提供
3.主程序启用eureka客户端
修改 item-service、user-service 和 order-service,主程序添加 @EnableDiscoveryClient 注解,也就是在主启动类中添加注解@EnableDiscoveryClient
4.启动服务,在eureka中查看注册信息