近来打仗了公司内部开发的项目,涉及到了Config设置中心河eureka服务注册中心,从前只用过Nacos服务设置中心,以是边学边试搭建了一个简朴的微服务的项目框架,同时记录一下自己踩过的坑。注:该demo中使用了远程调用服务,以是引入了Feign调用。
1.从零到一搭建项目
首先创建一个maven项目,在这里我们构建一个父子项目,拆分为四个子项目:order、product、config、eureka,具体的项目结构如下:

父程序pom依靠如下:
- <properties>
- <java.version>1.8</java.version>
- <maven.compiler.source>8</maven.compiler.source>
- <maven.compiler.target>8</maven.compiler.target>
- <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
- <spring-cloud.version>2021.0.1</spring-cloud.version>
- <spring-cloud-alibaba.version>2022.0.0.0-RC2</spring-cloud-alibaba.version>
- <mybatis-spring-boot-starter.version>3.0.2</mybatis-spring-boot-starter.version>
- <spring-boot.version>2.6.4</spring-boot.version>
- <mybatis-plus.version>3.5.3.1</mybatis-plus.version>
- <hutool-all.version>5.8.20</hutool-all.version>
- <mysql.version>8.0.33</mysql.version>
- </properties>
- <dependencies>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- </dependency>
- </dependencies>
- <dependencyManagement>
- <dependencies>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-dependencies</artifactId>
- <version>${spring-boot.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-dependencies</artifactId>
- <version>${spring-cloud.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
- <groupId>com.alibaba.cloud</groupId>
- <artifactId>spring-cloud-alibaba-dependencies</artifactId>
- <version>${spring-cloud-alibaba.version}</version>
- <type>pom</type>
- <scope>import</scope>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- <version>${mybatis-plus.version}</version>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-jdbc</artifactId>
- <version>${spring-boot.version}</version>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- <version>${hutool-all.version}</version>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <version>${mysql.version}</version> <!-- 最新稳定版本 -->
- </dependency>
- </dependencies>
- </dependencyManagement>
复制代码 如果要改成自己的版本依靠,必要注意Spring Boot、Spring Cloud和eureka之间的对应关系,建议确定其中两个依靠的版本,然后由Maven自动引入剩余依靠。
2.构建eureka服务
2.1 服务包结构和设置
项目标启动序次是eureka->config->其他微服务,因为其他服务必要向eureka注册中心注册服务,以是在这里先搭建eureka注册中心。
eureka微服务结构如下:
eureka-server的pom文件如下:
- <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-web</artifactId>
- </dependency>
- </dependencies>
复制代码 application.yml:
- spring:
- application:
- name: eureka-server
- server:
- port: 8761
- eureka:
- instance:
- hostname: 127.0.0.1
- client:
- register-with-eureka: false
- fetch-registry: false
- service-url:
- default-Zone: http://127.0.0.1:8761/eureka
复制代码 2.2 eureka设置注意事项
- eureka启动类必要加入@EnableEurekaServer注解。
- eureka服务启动大概出现以下问题:
- Failed to configure a DataSource: 'url' attribute is not specified and no embedded datasource could be configured.
- Reason: Failed to determine a suitable driver class
复制代码 该问题出现的缘故原由是引入了spring-boot-starter-jdbc 的依靠,但是并没有正确设置数据库,可以在启动类注解中加入@SpringBootApplication(exclude = DataSourceAutoConfiguration.class),去撤除数据库资源的自动扫描。
- 在启动eureka服务之后,可以通过浏览器访问8761端口的方式来检测服务启动情况,同时在后续其他微服务发起注册之后,可以查看注册情况。
3.构建config设置中心
3.1 服务包结构和设置
config设置中心用来存放其他微服务的设置文件,当其他微服务启动时,从设置中心拉取设置文件,完成服务启动。在该demo中,我将项目设置文件存储到了本地,并没有利用git存储到云端。项目包结构如下:
将其他服务的设置文件放在了config目次下,同时必要在config设置文件中注明路径,xxx-test.yml表现测试环境下的设置,xxx-dev.yml表现开发环境下的设置,xxx-release.yml表现生产环境下的设置。在这里我仅引入了两个服务的dev环境下的设置。
pom文件如下:
- <!--eureka 客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-config-server</artifactId>
- </dependency>
复制代码 applictaion.yml如下,profiles.active=native表现设置文件存储在本地,cloud.config.server.native.search-locations表现设置文件存储的位置,即位于上一级目次的config目次下。
- server:
- port: 8888
- spring:
- application:
- name: config-server
- profiles:
- active: native
- cloud:
- config:
- server:
- native:
- search-locations: file:./config/,classpath:/config/
- eureka:
- client:
- service-url:
- defaultZone: http://localhost:8761/eureka
复制代码 config目次下的设置文件,我仅仅进行了数据库设置, 如下:
- spring:
- datasource:
- username: root
- password: ********
- url: jdbc:mysql://ip:port/database_name?characterEncoding=utf-8&zeroDateTimeBehavior=convertToNull&transformedBitIsBoolean=true&serverTimezone=GMT%2B8
- driver-class-name: com.mysql.cj.jdbc.Driver
- hikari:
- connection-test-query: select 1
- connection-timeout: 20000
- idle-timeout: 300000
- maximum-pool-size: 5
- minimum-idle: 5
复制代码 3.2 config设置注意事项
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-config-server</artifactId>
- </dependency>
复制代码
- 注意设置文件的取名方式,通常为{application}-{profile}.yml,application表现服务名,profile表现环境设置,如dev、test等,例如我这里的设置文件取名为order-server-dev.yml。
- 在config服务启动之后,可通过浏览器访问http://ip:port/{application.name}/{profile}查看设置文件,例如:http://localhost:8888/product-server/dev。
4.构建order服务
4.1 order服务包结构和设置
在该项目demo中,order服务远程调用product服务,获取商品名和商品价格。以是应当在order服务启动类上加上@EnableFeignClients。order-server的项目结构如下:

pom文件如下:
- <dependencies>
- <!--eureka 客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <!-- 版本可以省略,因为已经在父项目中定义 -->
- </dependency>
- <!--配置中心客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-bootstrap</artifactId>
- </dependency>
- </dependencies>
复制代码 设置文件的启动序次为bootstrap.yml->application.yml->设置中心设置,同时后续的设置会覆盖从前的设置,注意eureka注册服务名均为大写,bootstrap.yml和application.yml文件如下:
bootstrap.yml:
- spring:
- cloud:
- config:
- discovery:
- enabled: true
- service-id: CONFIG-SERVER
- name: ${spring.application.name}
- profile: ${spring.profiles.active}
- fail-fast: true
- eureka:
- client:
- service-url:
- default-zone: http://127.0.0.1:8761/eureka
- registry-fetch-interval-seconds: 30
复制代码 application.yml:
- server:
- port: 8081
- spring:
- application:
- name: order-server
- profiles:
- active: dev
复制代码 在bootstrap.yml中的config设置中指定了设置中心的服务id为CONFIG-SERVER,设置中心名称为order-server,设置环境为dev。
4.2 order服务设置注意事项
- 在引入bootstrap.yml后,无法启动项目,并报出如下如下错误,这个错误的缘故原由是,在springcloud2020版本之后,默认禁用了bootstrap设置文件的引入,以是必要我们手动引入相关依靠。
- Application failed to start due to an exception
- org.springframework.cloud.commons.ConfigDataMissingEnvironmentPostProcessor$ImportException: No spring.config.import set
复制代码 5. 构建product服务
5.1 product服务包结构和设置
product服务包结构如下:

pom文件如下:
- <dependencies>
- <!--eureka 客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-netflix-eureka-client</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-web</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-openfeign</artifactId>
- </dependency>
- <dependency>
- <groupId>cn.hutool</groupId>
- <artifactId>hutool-all</artifactId>
- </dependency>
- <dependency>
- <groupId>org.projectlombok</groupId>
- <artifactId>lombok</artifactId>
- </dependency>
- <dependency>
- <groupId>com.baomidou</groupId>
- <artifactId>mybatis-plus-boot-starter</artifactId>
- </dependency>
- <dependency>
- <groupId>mysql</groupId>
- <artifactId>mysql-connector-java</artifactId>
- <!-- 版本可以省略,因为已经在父项目中定义 -->
- </dependency>
- <!--配置中心客户端 -->
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-config</artifactId>
- </dependency>
- <dependency>
- <groupId>org.springframework.cloud</groupId>
- <artifactId>spring-cloud-starter-bootstrap</artifactId>
- </dependency>
- </dependencies>
复制代码 bootstrap.yml文件如下:
- spring:
- cloud:
- config:
- discovery:
- enabled: true
- service-id: CONFIG-SERVER
- name: ${spring.application.name}
- profile: ${spring.profiles.active}
- fail-fast: true
- eureka:
- client:
- service-url:
- default-zone: http://localhost:8761/eureka
- registry-fetch-interval-seconds: 30
复制代码 application.yml文件如下:
- server:
- port: 8080
- spring:
- application:
- name: product-server
- profiles:
- active: dev
复制代码 6. 编写product服务代码
6.1 数据库设计
- DROP TABLE IF EXISTS `product`;
- CREATE TABLE `product` (
- `id` int(0) NOT NULL AUTO_INCREMENT,
- `name` varchar(100) CHARACTER SET utf8mb4 COLLATE utf8mb4_0900_ai_ci NOT NULL,
- `price` decimal(10, 2) NOT NULL,
- `stock` int(0) NOT NULL,
- PRIMARY KEY (`id`) USING BTREE
- ) ENGINE = InnoDB AUTO_INCREMENT = 5 CHARACTER SET = utf8mb4 COLLATE = utf8mb4_0900_ai_ci ROW_FORMAT = Dynamic;
- -- ----------------------------
- -- Records of product
- -- ----------------------------
- INSERT INTO `product` VALUES (1, 'Laptop', 999.99, 10);
- INSERT INTO `product` VALUES (2, 'Smartphone', 499.99, 50);
- INSERT INTO `product` VALUES (3, 'Tablet', 299.99, 30);
- INSERT INTO `product` VALUES (4, 'Headphones', 79.99, 100);
- INSERT INTO `product` VALUES (5, 'Smartwatch', 199.99, 25);
复制代码 6.2 编写启动类
因为order为服务发起方,product服务为被调用方,以是product服务仅必要添加@SpringBootApplication和@MapperScan两个注解。
6.3 编写商品服务controller层
productController代码如下,编写了一个简朴api,通过id获取商品信息
- @RestController
- public class ProductController {
-
- @Resource
- private ProductService productService;
-
- @GetMapping("/api/product/getProduct")
- public ProductRespDTO product(@RequestParam("id")Integer id){
- return productService.getProductById(id);
- }
- }
复制代码 6.4 编写商品服务Service层
ProductService代码如下:
- public interface ProductService {
- ProductRespDTO getProductById(Integer id);
- }
复制代码 6.5 编写商品服务Service实现层
ProductServiceImpl代码如下,这里没有做复杂的逻辑处理,直接查数据库返回结果。我使用的是mybatis-plus,自带的函数,可以用其他取代。
- @Service
- public class ProductServiceImpl extends ServiceImpl<ProductMapper, ProductDO>implements ProductService {
-
- @Override
- public ProductRespDTO getProductById(Integer id) {
- LambdaQueryWrapper<ProductDO> queryWrapper = Wrappers.lambdaQuery(ProductDO.class)
- .eq(ProductDO::getId, id);
- ProductDO productDO = baseMapper.selectOne(queryWrapper);
- ProductRespDTO result=new ProductRespDTO();
- BeanUtil.copyProperties(productDO,result);
- return result;
- }
- }
复制代码 6.6 编写商品服务Dao层实体和mapper接口
引入lombok,利用在线网站天生实体类,网站地点:凝聚力开发,实体类如下:
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- @TableName("product")
- public class ProductDO {
- private Integer id; // 产品 ID
- private String name; // 产品名称
- private BigDecimal price; // 产品价格
- private Integer stock; // 产品库存
- }
复制代码 mapper层接口如下:
- @Mapper
- public interface ProductMapper extends BaseMapper<ProductDO> {
- }
复制代码 6.7 请求返回实体类
ProductRespDTO实体,仅返回商品的名称和价格。
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- public class ProductRespDTO {
- private String name; // 产品名称
- private BigDecimal price; // 产品价格
- }
复制代码 7. 编写Order服务
7.1 编写订单服务启动类
Order服务必要远程调用Product服务,以是这里涉及到Feign调用。OrderApplication.class如下:
- @SpringBootApplication
- @EnableFeignClients
- public class OrderApplication {
- public static void main(String[] args) {
- SpringApplication.run(OrderApplication.class,args);
- }
- }
复制代码 7.2 编写订单服务controller层
- @RestController
- public class OrderController {
- @Resource
- private ProductFeignClient productFeignClient;
- @GetMapping("/api/getOrder")
- public ProductRespDTO getProduct(@RequestParam("id")Integer id){
- return productFeignClient.getProduct(id);
- }
- }
复制代码 7.3 编写订单服务返回实体类
- @Data
- @Builder
- @AllArgsConstructor
- @NoArgsConstructor
- public class ProductRespDTO {
- private String name; // 产品名称
- private BigDecimal price; // 产品价格
- }
复制代码 7.4 编写远程调用接口
注意,因为在eureka服务注册中心默认注册服务名为大写,以是引入也必要用大写,同时注意远程调用的接口路径必要与被调用api的路径一致,具体代码如下:
- @FeignClient(value = "PRODUCT-SERVER")
- public interface ProductFeignClient {
- @GetMapping("/api/product/getProduct")
- ProductRespDTO getProduct(@RequestParam("id")Integer id);
- }
复制代码 8. 总结
微服务启动序次为:eureka->config->order/product。在后续项目启动之后可从eureka注册服务中心查看微服务注册情况,可直接访问对应接口传参进行测试。
例如,可使用apifox大概postman对接口测试,来查看微服务搭建情况:
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |