服务间调用
1.在父工程中引入所有版本依赖
<packaging>pom</packaging>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.0.4.RELEASE</version>
<relativePath/>
</parent>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<project.reporting.outputEncoding>UTF-8</project.reporting.outputEncoding>
<java.version>1.8</java.version>
<spring-cloud.version>Finchley.SR1</spring-cloud.version>
<mapper.starter.version>2.0.3</mapper.starter.version>
<mysql.version>5.1.32</mysql.version>
</properties>
<dependencyManagement>
<dependencies>
<!--springCloud-->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-dependencies</artifactId>
<version>${spring-cloud.version}</version>
<type>pom</type>
<scope>import</scope>
</dependency>
<!--通用Mapper启动器-->
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
<version>${mapper.starter.version}</version>
</dependency>
<!--mysql驱动-->
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
<version>${mysql.version}</version>
</dependency>
</dependencies>
</dependencyManagement>
<dependencies>
<dependency>
<groupId>org.projectlombok</groupId>
<artifactId>lombok</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin></plugins>
</build>
服务提供者
2.创建子工程user-service为提供服务的子项目
依赖:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
<dependency>
<groupId>mysql</groupId>
<artifactId>mysql-connector-java</artifactId>
</dependency>
<dependency>
<groupId>tk.mybatis</groupId>
<artifactId>mapper-spring-boot-starter</artifactId>
</dependency>
</dependencies>
3.在user-service的项目中的resource创建application.yml文件,并导入相关配置
server:
port: 8081
spring:
datasource:
url: jdbc:mysql://localhost:3306/mydb01
username: root
password: root
mybatis:
type-aliase-package: cn.sddm.user.pojo
4.创建启动类
@SpringBootApplication
@MapperScan("cn.itcast.user.mapper")
public class UserApplication {
public static void main(String[] args) {
SpringApplication.run(UserApplication.class,args);
}
}
5.创建实体类
@Table(name = "tb_user")
@Data
public class User {
@Id
@KeySql(useGeneratedKeys = true)
private Long id;
private String username; //用户名
private String password;//密码
private String name;//姓名
private Integer age;//年龄
private Integer sex;//性别,1男性,2女性
private Date birthday;//出生日期
private Date created;//创建时间
private String note;//备注
}
6.创建mapper接口
public interface UserMapper extends Mapper<User> {
}
7.创建service
@Service
public class UserService {
@Autowired
private UserMapper userMapper;
public User queryById(Long id){
return userMapper.selectByPrimaryKey(id);
}
}
8.创建对外提供接口的控制器
@Controller
@RequestMapping("user")
public class UserController {
@Autowired
private UserService userService;
@GetMapping("/{id}")
@ResponseBody
public User queryBuId(@PathVariable("id") Long id){
return userService.queryById(id);
}
}
服务调用者
9.创建子项目,导入依赖
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
</dependencies>
10.编写启动类
@SpringBootApplication
public class ConsumerApplication {
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
public static void main(String[] args) {
SpringApplication.run(ConsumerApplication.class,args);
}
}
11.编写实体类
@Data
public class User {
private Long id;
private String userName; //用户名
private String password;//密码
private String name;//姓名
private Integer age;//年龄
private Integer sex;//性别,1男性,2女性
private Date birthday;//出生日期
private Date created;//创建时间
private Date updated;//更新时间
}
12.编写controller,在controller中直接 调用RestTemplate,远程访问user-service的服务接口
@RestController
@RequestMapping("consumer")
public class ConsumerController {
@Autowired
private RestTemplate restTemplate;
@GetMapping("/{id}")
public User queryById(@PathVariable("id")Long id){
String url = "http://localhost:8081/user/"+id;
User user = restTemplate.getForObject(url,User.class);
return user;
}
}
13.创建数据库
DROP TABLE IF EXISTS `tb_user`;
CREATE TABLE `tb_user` (
`id` bigint(20) NOT NULL AUTO_INCREMENT,
`username` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
`password` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
`name` varchar(100) COLLATE utf8mb4_bin DEFAULT NULL,
`age` int(11) DEFAULT NULL,
`sex` int(11) DEFAULT NULL,
`birthday` date DEFAULT NULL,
`created` date DEFAULT NULL,
`note` varchar(1000) COLLATE utf8mb4_bin DEFAULT NULL,
PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=12 DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin;
-- ----------------------------
-- Records of tb_user
-- ----------------------------
INSERT INTO `tb_user` VALUES ('1', 'liuyan', '123456', '柳岩', '21', '2', '2020-12-31', '2020-12-31', '柳岩真的漂亮');
INSERT INTO `tb_user` VALUES ('2', 'liubei', '1234564', '刘备', '21', '2', '2020-12-09', '2020-12-15', '完了完了');
INSERT INTO `tb_user` VALUES ('3', 'zhangsan', '123456', '李四', '21', '3', '2020-12-31', '2020-12-31', '开会开会');
INSERT INTO `tb_user` VALUES ('4', 'zhangsan', '123456', '王五', '21', '3', '2020-12-23', '2020-12-30', '开会开会');
INSERT INTO `tb_user` VALUES ('5', 'zhangsan', '123456', '林六', '21', '3', '2020-12-31', '2020-12-30', '开会开会');
INSERT INTO `tb_user` VALUES ('6', 'zhangsan', '123456', '周器', '21', '3', '2020-12-15', '2021-01-08', '开会开会');
INSERT INTO `tb_user` VALUES ('7', 'zhangsan', '123456', '周杰伦', '21', '3', '2021-01-08', '2020-12-24', '开会开会');
INSERT INTO `tb_user` VALUES ('8', 'zhangsan', '123456', '七里香', '21', '3', '2020-12-31', '2020-12-31', '开会开会');
INSERT INTO `tb_user` VALUES ('9', 'zhangsan', '123456', '晴天', '21', '3', '2020-12-15', null, '开会开会');
INSERT INTO `tb_user` VALUES ('10', 'zhangsan', '123456', '安静', '21', '3', '2020-12-14', '2020-12-15', '开会开会');
INSERT INTO `tb_user` VALUES ('11', 'zhangsan', '123456', '张三', '21', '3', '2020-12-22', '2020-12-07', '开会开会');
INSERT INTO `tb_user` VALUES ('10', 'zhangsan', '123456', '安静', '21', '3', '2020-12-14', '2020-12-15', '开会开会');
INSERT INTO `tb_user` VALUES ('11', 'zhangsan', '123456', '张三', '21', '3', '2020-12-22', '2020-12-07', '开会开会');
12、项目结构
13、存在问题
user-server:一个提供根据id查询用户的微服务
consumer-demo:一个服务调用者,通过RestTemplate远程调用user-server
存在问题:
- 在consumer中,我们把url地址硬编码到了代码中,不方便后期维护
- consumer需要记忆user-service的地址,如果出现变更,可能得不到通知,地址将失效
- consumer不清楚user-service的状态,服务宕机也不知道
- user-service只有1台服务,不具备高可用性
- 即便user-service形成集群,consumer还需自己实现负载均衡
其实上面说的问题,概括一下就是分布式服务必然要面临的问题:
- 服务管理
- 如何自动注册和发现
- 如何实现状态监管
- 如何实现动态路由
- 服务如何实现负载均衡
- 服务如何解决容灾问题
- 服务如何实现统一配置