[TOC] ## 在evm中新建一个微服务 如何在evm新建一个新的微服务? ### 1-新建一个module 右键父级module,新建一个maven module: ![](https://gitee.com/cowboy2014/cloud2020-config/raw/master//pictures/20210103204529.png) ### 2-编辑pom.xml ```xml <dependencies> <!-- evm-common模块 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>evm-common</artifactId> <version>1.0-SNAPSHOT</version> <scope>compile</scope> </dependency> <!-- 关系型数据库配置 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>db-spring-boot-starter</artifactId> </dependency> <!-- 非关系型数据库配置 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>redis-spring-boot-starter</artifactId> </dependency> <!-- 日志中心 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>log-spring-boot-starter</artifactId> </dependency> <!-- 公共实体配置 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>common-spring-boot-starter</artifactId> </dependency> <!-- 资源服务器配置 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>uaa-client-spring-boot-starter</artifactId> </dependency> <!-- API文档配置 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>swagger-spring-boot-starter</artifactId> </dependency> <!-- 熔断限流组件 --> <dependency> <groupId>com.keyou.evm</groupId> <artifactId>sentinel-spring-boot-starter</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-web</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-starter-actuator</artifactId> </dependency> <dependency> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-configuration-processor</artifactId> <optional>true</optional> </dependency> <!-- 选用nacos时打开--> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-discovery</artifactId> </dependency> <dependency> <groupId>com.alibaba.cloud</groupId> <artifactId>spring-cloud-starter-alibaba-nacos-config</artifactId> </dependency> <dependency> <groupId>com.alibaba.csp</groupId> <artifactId>sentinel-datasource-nacos</artifactId> </dependency> </dependencies> <!-- 形成带第三方jar包的可执行jar包,jar包目录结构如下 application.properties lib META-INF mybatis org --> <build> <plugins> <plugin> <groupId>org.springframework.boot</groupId> <artifactId>spring-boot-maven-plugin</artifactId> <executions> <execution> <goals> <goal>repackage</goal> </goals> </execution> </executions> </plugin> <!-- 首先加入pom ${docker.image.prefix} : 这个是你的dockerhub注册上面的名字 gitgeek 这个是我注册的 ${project.artifactId} : 项目的名称 dockerDirectory : dockerfile的文件路径 --> <plugin> <groupId>com.spotify</groupId> <artifactId>docker-maven-plugin</artifactId> <version>0.4.13</version> <configuration> <imageName>${docker.image.prefix}/${project.artifactId}</imageName> <dockerDirectory>src/main/docker</dockerDirectory> <dockerHost>${docker.host}</dockerHost> <resources> <resource> <targetPath>/</targetPath> <directory>${project.build.directory}</directory> <include>${project.build.finalName}.jar</include> </resource> </resources> </configuration> </plugin> </plugins> <resources> <!-- 打包java代码资源 --> <resource> <directory>src/main/java</directory> <includes> <include>**/*.xml</include> </includes> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> </resource> <resource> <directory>src/main/profiles/${app.env}</directory> <filtering>false</filtering> </resource> </resources> <finalName>${project.artifactId}</finalName> </build> ``` ### 3-创建启动类 >[info] 启动类是Springboot项目启动的入口。 ![](https://gitee.com/cowboy2014/cloud2020-config/raw/master//pictures/20210103204600.png) ```java @Configuration @EnableLogging @EnableDiscoveryClient @SpringBootApplication @EnableApiIdempotent @MapperScan("com.keyou.evm.*.mapper,com.keyou.evm.*.dao") public class ApiFakerApp { public static void main(String[] args) { // 固定端口启动 // SpringApplication.run(UserCenterApp.class, args); //随机端口启动 SpringApplication app = new SpringApplication(ApiFakerApp.class); app.addListeners(new PortApplicationEnvironmentPreparedEventListener()); app.run(args); } } ``` ### 4-创建swagger配置类 ![](https://gitee.com/cowboy2014/cloud2020-config/raw/master//pictures/20210103204639.png) 添加配置信息: ```java @Component @Configuration @EnableSwagger2 public class SwaggerConfig implements WebMvcConfigurer { @Bean public Docket createRestApi() { ParameterBuilder tokenPar = new ParameterBuilder(); List<Parameter> pars = new ArrayList<>(); tokenPar.name("Authorization").description("令牌"). modelRef(new ModelRef("string")). parameterType("header").required(false).build(); pars.add(tokenPar.build()); return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() // .apis(RequestHandlerSelectors.basePackage("com.keyou.evm")) .apis(RequestHandlerSelectors.any()) // .paths(input -> PathSelectors.regex("/user.*").apply(input) || PathSelectors.regex("/permissions.*").apply(input) // || PathSelectors.regex("/roles.*").apply(input) || PathSelectors.regex("/menus.*").apply(input) || PathSelectors.regex("/test.*").apply(input) // ) .paths(PathSelectors.any()) .build().globalOperationParameters(pars); } private ApiInfo apiInfo() { ===>修改正确的title和description return new ApiInfoBuilder().title("商城访客系统api").description("商城访客系统api").version("1.0").build(); } @Bean public ViewResolver viewResolver() { InternalResourceViewResolver resolver = new InternalResourceViewResolver(); resolver.setViewClass(JstlView.class); resolver.setPrefix("/"); resolver.setSuffix(".html"); return resolver; } @Bean public MessageSource messageSource() { ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); messageSource.setBasename("messages"); return messageSource; } @Override public void addResourceHandlers(ResourceHandlerRegistry registry) { // super.addResourceHandlers(registry); registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); } @Override public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { configurer.enable(); } } ``` ### 5-添加配置信息 #### application.yml ```xml #端口配置 server: port: 6001 #固定端口 # port: ${randomServerPort.value[7000,7005]} #随机端口 spring: datasource: # JDBC 配置(驱动类自动从url的mysql识别,数据源类型自动识别) url: jdbc:mysql://192.168.30.22:3306/zbj?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false username: root password: root driver-class-name: com.mysql.cj.jdbc.Driver #连接池配置(通常来说,只需要修改initialSize、minIdle、maxActive initial-size: 1 max-active: 20 min-idle: 1 # 配置获取连接等待超时的时间 max-wait: 60000 #打开PSCache,并且指定每个连接上PSCache的大小 pool-prepared-statements: true max-pool-prepared-statement-per-connection-size: 20 validation-query: SELECT 'x' test-on-borrow: false test-on-return: false test-while-idle: true #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 time-between-eviction-runs-millis: 60000 #配置一个连接在池中最小生存的时间,单位是毫秒 min-evictable-idle-time-millis: 300000 filters: stat,wall # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter #是否启用StatFilter默认值true web-stat-filter.enabled: true web-stat-filter.url-pattern: /* web-stat-filter.exclusions: "*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*" web-stat-filter.session-stat-max-count: 1000 web-stat-filter.profile-enable: true # StatViewServlet配置 #展示Druid的统计信息,StatViewServlet的用途包括:1.提供监控信息展示的html页面2.提供监控信息的JSON API #是否启用StatViewServlet默认值true stat-view-servlet.enabled: true #根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html例如: #http://110.76.43.235:9000/druid/index.html #http://110.76.43.235:8080/mini-web/druid/index.html stat-view-servlet.url-pattern: /druid/* #允许清空统计数据 stat-view-servlet.reset-enable: true stat-view-servlet.login-username: admin stat-view-servlet.login-password: admin #StatViewSerlvet展示出来的监控信息比较敏感,是系统运行的内部情况,如果你需要做访问控制,可以配置allow和deny这两个参数 #deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。如果allow没有配置或者为空,则允许所有访问 #配置的格式 #<IP> #或者<IP>/<SUB_NET_MASK_size>其中128.242.127.1/24 #24表示,前面24位是子网掩码,比对的时候,前面24位相同就匹配,不支持IPV6。 #stat-view-servlet.allow= #stat-view-servlet.deny=128.242.127.1/24,128.242.128.1 # Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置 #aop-patterns= # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔 ################### mysq end ########################## # zipkin: # base-url: http://127.0.0.1:11008 redis: ################### redis 单机版 start ########################## host: 192.168.30.22 port: 6379 timeout: 6000 database: 8 lettuce: pool: max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽) max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8 max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0 shutdown-timeout: 100ms ################### redis 单机版 end ########################## # cluster: # nodes: 130.75.131.237:7000,130.75.131.238:7000,130.75.131.239:7000,130.75.131.237:7001,130.75.131.238:7001,130.75.131.239:7001 # #130.75.131.237:7000,130.75.131.238:7000,130.75.131.239:7000,130.75.131.237:7001,130.75.131.238:7001,130.75.131.239:7001 # #192.168.3.157:7000,192.168.3.158:7000,192.168.3.159:7000,192.168.3.157:7001,192.168.3.158:7001,192.168.3.159:7001 # timeout: 1000 # 连接超时时间(毫秒) # lettuce: # pool: # max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽) # max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8 # max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException # min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0 # shutdown-timeout: 100ms mybatis-plus: global-config: banner: false configuration: log-impl: org.apache.ibatis.logging.stdout.StdOutImpl mapper-locations: classpath*:com/keyou/*/*/mapper/*Mapper.xml security: oauth2: ignored: /users-anon/** , /doc.html ,/document.html ,/users/save token: store: type: redis #设置最大超时时间 ribbon: ServerListRefreshInterval: 10 #刷新服务列表源的间隔时间 OkToRetryOnAllOperations: true MaxAutoRetries: 1 MaxAutoRetriesNextServer: 1 ReadTimeout: 16000 ConnectTimeout: 16000 #设置最大容错超时时间 hystrix: command: default: execution: timeout: enabled: true isolation: thread: timeoutInMilliseconds: 16000 logging: level: com.keyou.evm: INFO org.hibernate: INFO org.hibernate.type.descriptor.sql.BasicBinder: TRACE org.hibernate.type.descriptor.sql.BasicExtractor: TRACE # com.neusoft: DEBUG # com.netflix: DEBUG #用于心跳检测输出的日志 ``` #### bootstrap.yml `bootstrap.yml`的加载优先级是高于`application.yml`的,用于连接nacos获取配置信息,以及完成服务的注册。 ```yaml spring: cloud: nacos: config: # 共享配置的DataId,多个使用,分隔 # 越靠后,优先级越高; # .yaml后缀不能少,只支持yaml/properties shared-dataids: common.yaml ### 共享配置 refreshable-dataids: common.yaml ### 可刷新共享配置 server-addr: 192.168.30.22:8848 ### nacos server地址 file-extension: yaml ### dataId扩展名 namespace: f4db1f33-61e5-496e-a2bd-8b390918c14e #命名空间 代指某个环境 sentinel: transport: # 指定sentinel 控制台的地址 dashboard: 127.0.0.1:8080 eager: true application: name: api-faker #metrics management: endpoints: web: exposure: include: "*" endpoint: chaosmonkey: enabled: true health: show-details: always ``` >[warning] 恭喜你,到此结束,一个新的应用就创建成功了。