上一节已经添加了eureka服务发现和服务治理中心,里面只有它自己显然是没有啥用的,这时候我们自己写好的业务微服务如何注册到注册中心呢?
做微服务架构首先是微服务的划分,这次的例子主要以用户购买商品并下单的方式来划分微服务,总共划分三个微服务:
- cloud-user 用户微服务(用来维护用户基本信息)
- cloud-order 订单微服务 (用来维护订单基本信息)
- cloud-good 商品微服务 (用来维护商品基本信息)
不仅划分服务还划分数据库,每个微服务对应一个数据库这也是最大化的解耦,这种方式比如写了一个角色权限的微服务,其实用户角色权限大部分系统都差不多,有其他项目要用,只需要将一个微服务jar包和此微服务对应的数据库拿过去就可以了,这样就可以很方便的完成项目重复功能的复用
项目大体功能就是用户购买商品然后下单,会有服务调用操作,异步操作,消息提醒,数据聚合,网关路由,权限限制等。
其他两个微服务的注册后面会讲解,这节主要讲解用户微服务的编写和注册
目录
1、创建数据库表结构
create schema if not exists cloud_user collate utf8mb4_0900_ai_ci; create table if not exists user ( id char(32) not null, user_name varchar(20) not null comment '用户名', nick_name varchar(20) not null comment '用户昵称', user_pswd varchar(50) not null comment '用户密码', create_date datetime not null comment '创建日期', create_by char(32) not null comment '创建人', update_date datetime not null comment '更新日期', update_by char(32) not null comment '更新人', constraint user_id_uindex unique (id) ) comment '用户表'; alter table user add primary key (id);
2、新建cloud-user微服务子模块
新建方式和上一节是类似的,这里就不再说了
3、添加用户微服务需要的依赖
在用户微服务pom.xml中添加如下代码
这里集成了druid数据库连接池,mysql jdbc驱动,jpa以及服务注册需要的依赖
<?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"> <parent> <artifactId>spring-cloud-study</artifactId> <groupId>com.apgblogs</groupId> <version>1.0-SNAPSHOT</version> </parent> <modelVersion>4.0.0</modelVersion> <groupId>com.apgblogs</groupId> <artifactId>cloud-user</artifactId> <dependencies> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-data-jpa</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <scope>runtime</scope> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-test</artifactId> <scope>test</scope> </dependency> <!-- 数据库连接池 --> <dependency> <groupId>com.alibaba</groupId> <artifactId>druid-spring-boot-starter</artifactId> <version>1.1.10</version> </dependency> <dependency> <groupId>log4j</groupId> <artifactId>log4j</artifactId> <version>1.2.17</version> </dependency> <dependency> <groupId>com.google.code.gson</groupId> <artifactId>gson</artifactId> <version>2.8.5</version> </dependency> <!--服务客户端 --> <dependency> <groupId>org.springframework.cloud</groupId> <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId> </dependency> </dependencies> </project>
4、创建controller,entity,service,repository等包
创建如下图所示的包和对应的类,entity中的实体类可以采用表映射的方式自动生成,对于如何表映射生成实体类可以访问下面的这篇文章链接
UserEntity类
package com.apgblogs.clouduser.entity; import org.hibernate.annotations.GenericGenerator; import org.springframework.data.annotation.CreatedDate; import org.springframework.data.annotation.LastModifiedDate; import org.springframework.data.jpa.domain.support.AuditingEntityListener; import javax.persistence.*; import java.sql.Timestamp; import java.util.Objects; /** * @author xiaomianyang * @description * @date 2019-07-02 20:10 */ @Entity @EntityListeners(AuditingEntityListener.class) @Table(name = "user", schema = "cloud_user", catalog = "") public class UserEntity { private String id; private String userName; private String nickName; private String userPswd; private Timestamp createDate; private String createBy; private Timestamp updateDate; private String updateBy; @Id @Column(name = "id", nullable = false, length = 32) @GenericGenerator(name = "jpa-uuid", strategy = "uuid") @GeneratedValue(generator = "jpa-uuid") public String getId() { return id; } public void setId(String id) { this.id = id; } @Basic @Column(name = "user_name", nullable = false, length = 20) public String getUserName() { return userName; } public void setUserName(String userName) { this.userName = userName; } @Basic @Column(name = "nick_name", nullable = false, length = 20) public String getNickName() { return nickName; } public void setNickName(String nickName) { this.nickName = nickName; } @Basic @Column(name = "user_pswd", nullable = false, length = 50) public String getUserPswd() { return userPswd; } public void setUserPswd(String userPswd) { this.userPswd = userPswd; } @Basic @Column(name = "create_date", nullable = false) @CreatedDate public Timestamp getCreateDate() { return createDate; } public void setCreateDate(Timestamp createDate) { this.createDate = createDate; } @Basic @Column(name = "create_by", nullable = false, length = 32) public String getCreateBy() { return createBy; } public void setCreateBy(String createBy) { this.createBy = createBy; } @Basic @Column(name = "update_date", nullable = false) @LastModifiedDate public Timestamp getUpdateDate() { return updateDate; } public void setUpdateDate(Timestamp updateDate) { this.updateDate = updateDate; } @Basic @Column(name = "update_by", nullable = false, length = 32) public String getUpdateBy() { return updateBy; } public void setUpdateBy(String updateBy) { this.updateBy = updateBy; } @Override public boolean equals(Object o) { if (this == o) return true; if (o == null || getClass() != o.getClass()) return false; UserEntity that = (UserEntity) o; return Objects.equals(id, that.id) && Objects.equals(userName, that.userName) && Objects.equals(nickName, that.nickName) && Objects.equals(userPswd, that.userPswd) && Objects.equals(createDate, that.createDate) && Objects.equals(createBy, that.createBy) && Objects.equals(updateDate, that.updateDate) && Objects.equals(updateBy, that.updateBy); } @Override public int hashCode() { return Objects.hash(id, userName, nickName, userPswd, createDate, createBy, updateDate, updateBy); } }
UserRepository接口
package com.apgblogs.clouduser.repository; import com.apgblogs.clouduser.entity.UserEntity; import org.springframework.data.jpa.repository.JpaRepository; /** * @author xiaomianyang * @description * @date 2019-07-02 20:12 */ public interface UserRepository extends JpaRepository<UserEntity,String> { }
UserServiceImpl 用户业务实现类
package com.apgblogs.clouduser.service; import com.apgblogs.clouduser.entity.UserEntity; import com.apgblogs.clouduser.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; /** * @author xiaomianyang * @description * @date 2019-07-02 20:15 */ @Service public class UserServiceImpl { @Autowired private UserRepository userRepository; /** * @description 通过用户Id获取用户 * @author xiaomianyang * @date 2019-07-02 20:16 * @param [id] * @return com.apgblogs.clouduser.entity.UserEntity */ public UserEntity getUser(String id){ if(!userRepository.existsById(id)){ return null; } return userRepository.findById(id).get(); } /** * @description 保存用户 * @author xiaomianyang * @date 2019-07-02 20:19 * @param [userEntity] * @return com.apgblogs.clouduser.entity.UserEntity */ public UserEntity saveUser(UserEntity userEntity){ if(StringUtils.isEmpty(userEntity)){ return null; } userEntity.setCreateBy("sys"); userEntity.setUpdateBy("sys"); return userRepository.save(userEntity); } }
UserController 用户控制器
package com.apgblogs.clouduser.service; import com.apgblogs.clouduser.entity.UserEntity; import com.apgblogs.clouduser.repository.UserRepository; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.stereotype.Service; import org.springframework.util.StringUtils; /** * @author xiaomianyang * @description * @date 2019-07-02 20:15 */ @Service public class UserServiceImpl { @Autowired private UserRepository userRepository; /** * @description 通过用户Id获取用户 * @author xiaomianyang * @date 2019-07-02 20:16 * @param [id] * @return com.apgblogs.clouduser.entity.UserEntity */ public UserEntity getUser(String id){ if(!userRepository.existsById(id)){ return null; } return userRepository.findById(id).get(); } /** * @description 保存用户 * @author xiaomianyang * @date 2019-07-02 20:19 * @param [userEntity] * @return com.apgblogs.clouduser.entity.UserEntity */ public UserEntity saveUser(UserEntity userEntity){ if(StringUtils.isEmpty(userEntity)){ return null; } userEntity.setCreateBy("sys"); userEntity.setUpdateBy("sys"); return userRepository.save(userEntity); } }
5、编写启动类,添加服务发现和启用jpa注解
UserApplication 启动类
@EnableJpaAuditing 主要是用来自动生成实体类创建日期和修改日期的
@EnableDiscoveryClient 表示该类是一个服务客户端,可以被服务注册中心所发现
package com.apgblogs.clouduser; import org.springframework.boot.SpringApplication; import org.springframework.boot.autoconfigure.SpringBootApplication; import org.springframework.cloud.client.discovery.EnableDiscoveryClient; import org.springframework.data.jpa.repository.config.EnableJpaAuditing; /** * @author xiaomianyang * @description * @date 2019-07-02 20:07 */ @SpringBootApplication @EnableJpaAuditing @EnableDiscoveryClient public class UserApplication { public static void main(String[] args) { SpringApplication.run(UserApplication.class,args); } }
6、编写配置文件
创建两个配置文件,如下图
application.yml
以下配置文件主要是连接数据库和jpa的配置,这些之前springBoot都有介绍,eureka就是服务注册中心地址的配置,配置了这个注解在配合启动类上的@EnableDiscoveryClient注解就可以完成服务的注册了
server: port: 8881 spring: datasource: name: druidDataSource type: com.alibaba.druid.pool.DruidDataSource driver-class-name: com.mysql.cj.jdbc.Driver url: jdbc:mysql://apg-server:3306/cloud_user?useUnicode=true&characterEncoding=UTF-8&autoReconnect=true&failOverReadOnly=false&serverTimezone=Asia/Shanghai username: root password: 123456 druid: filters: stat,wall,log4j,config max-active: 100 initial-size: 1 max-wait: 60000 min-idle: 1 time-between-eviction-runs-millis: 60000 min-evictable-idle-time-millis: 300000 validation-query: select 'x' test-while-idle: true test-on-borrow: false test-on-return: false pool-prepared-statements: true max-open-prepared-statements: 50 max-pool-prepared-statement-per-connection-size: 20 web-stat-filter: exclusions: "*.js,*.gif,*.jpg,*.png,*.css,*.ico,/druid/*" url-pattern: /* stat-view-servlet: allow: 127.0.0.1 deny: apg-server login-username: admin login-password: admin reset-enable: true jpa: database-platform: org.hibernate.dialect.MySQL5InnoDBDialect show-sql: true hibernate: ddl-auto: none application: name: cloud-user #服务注册地址配置 eureka: client: service-url: defaultZone: http://localhost:8801/eureka/ instance: prefer-ip-address: true
log4j.properties log属性文件
log4j.rootLogger=debug, stdout, R log4j.appender.stdout=org.apache.log4j.ConsoleAppender log4j.appender.stdout.layout=org.apache.log4j.PatternLayout log4j.appender.stdout.layout.ConversionPattern=%5p - %m%n log4j.appender.R=org.apache.log4j.RollingFileAppender log4j.appender.R.File=log4j.log log4j.appender.R.MaxFileSize=100KB log4j.appender.R.MaxBackupIndex=1 log4j.appender.R.layout=org.apache.log4j.PatternLayout log4j.appender.R.layout.ConversionPattern=%p %t %c - %m%n
7、注释掉之前Eureka的高可用将配置2注释掉,目前还用不到所以也没必要启动那么多服务
在eureka微服务中对配置文件以下代码进行注册
8、启动项目访问测试
将Eureka和User两个微服务同时启动,也可以先启动Eureka在启动User,都可以的。
访问服务注册中心看看User微服务是不是已经出现了
如果出现以下的应用名那就用户微服务注册成功了
9、用postMan对用户微服务进行接口测试
新增用户接口测试
通过用户Id查询用户测试
10、文章源码地址
至此用户微服务就已经完美注册到服务中心了,也完成了用户微服务基本的新增用户和获取单个用户的restFul风格的接口,下一节会继续讲解后续的操作
你好,博主,UserController 和UserServiceImpl 代码是一样的。。。