cloud-demo(父项目)
新建三个子模块
user-service:用户服务
order-service:订单服务
eureka-server:注册中心
<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.0modelVersion>
<groupId>com.hzy.demogroupId>
<artifactId>cloud-demoartifactId>
<version>1.0version>
<modules>
<module>user-servicemodule>
<module>order-servicemodule>
<module>eureka-servermodule>
modules>
<packaging>pompackaging>
<parent>
<groupId>org.springframework.bootgroupId>
<artifactId>spring-boot-starter-parentartifactId>
<version>2.3.9.RELEASEversion>
<relativePath/>
parent>
<properties>
<project.build.sourceEncoding>UTF-8project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8project.reporting.outputEncoding>
<java.version>1.8java.version>
<spring-cloud.version>Hoxton.SR10spring-cloud.version>
<mysql.version>8.0.17mysql.version>
<mybatis.version>2.1.1mybatis.version>
properties>
<dependencyManagement>
<dependencies>
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-dependenciesartifactId>
<version>${spring-cloud.version}version>
<type>pomtype>
<scope>importscope>
dependency>
<dependency>
<groupId>mysqlgroupId>
<artifactId>mysql-connector-javaartifactId>
<version>${mysql.version}version>
dependency>
<dependency>
<groupId>org.mybatis.spring.bootgroupId>
<artifactId>mybatis-spring-boot-starterartifactId>
<version>${mybatis.version}version>
dependency>
dependencies>
dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombokgroupId>
<artifactId>lombokartifactId>
dependency>
dependencies>
project>
public interface UserMapper {
@Select("select * from tb_user where id = #{id}")
User findById(@Param("id") Long id);
}
@Data
public class User {
private Long id;
private String username;
private String address;
}
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id) {
return userMapper.findById(id);
}
}
@Slf4j
@RestController
@RequestMapping("/user")
public class UserController {
@Autowired
private UserService userService;
/**
* 路径: /user/110
* @param id 用户id
* @return 用户
*/
@GetMapping("/{id}")
public User queryById(@PathVariable("id") Long id) {
return userService.queryById(id);
}
}
@MapperScan("com.hzy.user.mapper")
@SpringBootApplication
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class, args);
}
}
public interface OrderMapper {
@Select("select * from tb_order where id = #{id}")
Order findById(Long id);
}
@Data
public class Order {
private Long id;
private Long price;
private String name;
private Integer num;
private Long userId;
private User user;
}
@Data
public class User {
private Long id;
private String username;
private String address;
}
@Service
public class OrderService {
@Autowired
private OrderMapper orderMapper;
@Autowired
private RestTemplate restTemplate;
public Order queryOrderById(Long orderId) {
// 1.查询订单
Order order = orderMapper.findById(orderId);
// 2.利用RestTemplat发起http请求,查询用户
// 2.1 url路径
String url = "http://localhost:8081/user/"+order.getUserId();
// 2.2 发送http请求
User user = restTemplate.getForObject(url, User.class);
// 3.封装user到order
order.setUser(user);
// 4.返回
return order;
}
}
@MapperScan("com.hzy.order.mapper")
@SpringBootApplication
public class OrderApplication {
public static void main(String[] args) {
SpringApplication.run(OrderApplication.class, args);
}
@Bean
@LoadBalanced // 负载均衡注解
public RestTemplate restTemplate(){// 实现服务远程调用
return new RestTemplate();
}
}
<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">
<parent>
<artifactId>cloud-demoartifactId>
<groupId>com.hzy.demogroupId>
<version>1.0version>
parent>
<modelVersion>4.0.0modelVersion>
<artifactId>eureka-serverartifactId>
<properties>
<maven.compiler.source>8maven.compiler.source>
<maven.compiler.target>8maven.compiler.target>
properties>
<dependencies>
dependencies>
project>
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
我们在订单服务里面运程调用用户服务使用的url是:
String url = "http://localhost:8081/user/"+order.getUserId();
这种硬编码在用户服务地址改变后需要重新打包,并且以后用户服务会有多实例,使用硬编码有很强的局限性。
要解决这个问题就要用到注册中心。
注册中心是服务实现服务化管理的核心组件,类似于目录服务的作用,主要用来存储服务信息,譬如提供者 url 串、路由信息等。服务注
册中心是微服务架构中最基础的设施之一。
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-serverartifactId>
dependency>
@EnableEurekaServer
@SpringBootApplication
public class EurekaApplication {
public static void main(String[] args) {
SpringApplication.run(EurekaApplication.class, args);
}
}
server:
port: 10086 # 服务端口
spring:
application:
name: eurekaserver # eureka的服务名称
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
将user-service服务注册到eureka-server步骤如下:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
spring:
application:
name: userservice # user的服务名称 不写这个在Eureka注册中心中服务名会是 UNKNOWN
eureka:
client:
service-url: # eureka的地址信息
defaultZone: http://127.0.0.1:10086/eureka
下面,我们将order-service的逻辑修改:向eureka-server拉取user-service的信息,实现服务发现。
服务发现、服务注册统一都封装在eureka-client依赖,因此这一步与服务注册时一致。
在order-service的pom文件中,引入下面的eureka-client依赖:
<dependency>
<groupId>org.springframework.cloudgroupId>
<artifactId>spring-cloud-starter-netflix-eureka-clientartifactId>
dependency>
服务发现也需要知道eureka地址,因此第二步与服务注册一致,都是配置eureka信息:
在order-service中,修改application.yml文件,添加服务名称、eureka地址:
spring:
application:
name: orderservice
eureka:
client:
service-url:
defaultZone: http://127.0.0.1:10086/eureka
服务拉取是基于服务名称获取服务列表,然后在对服务列表做负载均衡
String url = "http://localhost:8081/user/"+order.getUserId();
----->
String url = "http://userservice/user/"+order.getUserId();
@Bean
@LoadBalanced // 负载均衡注解
public RestTemplate restTemplate(){
return new RestTemplate();
}
为了演示一个服务有多个实例的场景,我们添加一个SpringBoot的启动配置,再启动一个user-service。
端口号不能相同,修改端口号为8082
启动两个user-service实例: