Spring Cloud规范实战

  1. 云栖社区>
  2. 博客>
  3. 正文

Spring Cloud规范实战

王伏芃 2018-02-09 18:44:35 浏览1859
展开阅读全文

Spring cloud 架构建立规范文档


版本1.0


作者:阿伏(王伏芃)




目录

1. 建立规范的目的 3

2.模板源码位置 3

3.系统架构图 3

4.路由服务Zuul Server 4

5.MybatisGeneratorPlus生成器 9

6.业务应用服务SpringBoot Server 15

6.1 服务启动方法: 16

6.2 @EnableCaching 17

6.3 @EnableScheduling 18

6.4@EnableFeignClients(basePackages="com.pay.api.client") 19

6.5 @ComponentScan(basePackages = "com.pay.api") 19

6.6 @ServletComponentScan 20

6.7 @EnableCircuitBreaker 20

6.8 @EnableHystrixDashboard 21

6.9 @EnableDiscoveryClient 22

6.10 @EnableSwagger2 22

7.注册中心服务Eureka Server 24

7.1 在pom.xml里添加依赖: 24

7.2 在bootstrap.yml里面配置如此: 25

7.3 EurekaServerApplication.java 25

7.4 运行时界面如下 26

8.全链路监控服务Zipkin Server 26

8.1 pom.xml 26

8.2 Bootstrap.yml 27

8.3 ZipkinServerApplication.java 27

8.4 客户端sleuth配置 28

9.配置服务Config Server 29

9.1. Pom.xml 29

9.2. ConfigServerApplication.java 29

9.3. Config server 的yml的配置 30

9.4. Client端的Pom.xml 30

9.5 Client端的在代码中的使用 31

9.6 Client端的yml中的配置: 31

10.各种命名规范 31

10.1变量命名规范。 31

10.2 强制要求所有魔法值全部用KeyCommon这个类里的属性来替代。 32

10.3 所有抛出的异常在TemplateErrorCode里面定义。 32

10.4 方法名命名规范 32

11. 模板使用方法 33

11.1 从git上面下载代码,查看章节2。 33

11.2用STS打开。STS下载地址在http://spring.io/tools/sts 33

11.3 配置好maven和jdk 34

11.3 导入template源码 37

11.4 重命名模板里面的文件夹名称或者更改目录结构,改成自己要的包名。 41

11.5 把com.caituo.template替换成自己的包名。 41

11.6 启动方法 42

12.附上之前做的一整套架构。 44

13.阿里巴巴的P3C标准 45

13.1. P3C标准的pdf文档 45

13.2.P3C的Eclipse插件安装办法及启动检查 45








1. 建立规范的目的


是为了统一规格,提高代码的可读性,系统的易用性,可维护性。

本规范作为搭建spring cloud的指导文档。确保照着搭建就能成功。


2.模板源码位置

在公司的gitlab上面。

http://10.66.1.168:10080/wangfupeng/pay-template.git

如果没有权限,请联系胡立开(hulikai@91steel.com),赵超(zhaochao@91steel.com)


3.系统架构图


 


下面是介绍各种服务器和各种应用。


4.路由服务Zuul Server


代码目录如图所示:

 

其中bootstrap.yml里面的

spring:

  config:

    location: classpath:/${ENV:dev}/

这个注释说明,通过环境变量来读取ENV的值来决定在哪个目录里面找着application.yml

application.yml里配置如下:

spring:

  application:

    name: zuul


server:

  port: 8020


eureka:

  client:

    service-url:

      defaultZone: http://localhost:8010/eureka/


zuul: 

  routes:

    api-a:

      path: /service-a/**

      serviceId: service-a

    api-b:

      path: /service-b/**

      serviceId: service-b

  sensitive-headers:  #设置忽略的头信息,设置为空能解决会话保持问题

  add-host-header: true #设为true才能保持Host头信息处理正确

#这表示,我们不希望 /hello 接口被路由,调用 "/service-a"会跳转到"service-a"服务。路由必须配置一个可以被指定为"ant路径匹配原则"的"path",所以"/service-a/"只能匹配一个层级, 但"/service-a/*"可以匹配多级.


Ant匹配规则表

Wildcard Description  

? 匹配任何单字符  

* 匹配0或者任意数量的字符  

** 匹配0或者更多的目录


Pom.xml里面的配置如此:

<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>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-parent</artifactId>

<version>1.5.4.RELEASE</version>

<relativePath /> <!-- lookup parent from repository -->

</parent>


<modelVersion>4.0.0</modelVersion>

<groupId>com.caituo.server</groupId>

<artifactId>zuul</artifactId>

<version>66602</version>

<packaging>jar</packaging>


<name>zuul</name>

<url>http://maven.apache.org</url>


<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>Dalston.SR1</spring-cloud.version>

</properties>


<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-zuul</artifactId>

</dependency>

</dependencies>

<dependencyManagement>

<dependencies>

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-dependencies</artifactId>

<version>${spring-cloud.version}</version>

<type>pom</type>

<scope>import</scope>

</dependency>

</dependencies>

</dependencyManagement>



</project>

然后在ZuulApplication.java里面写上如下代码就行了。


package com.caituo.server;


import org.springframework.boot.SpringApplication;

import org.springframework.boot.web.servlet.ServletComponentScan;

import org.springframework.cloud.client.SpringCloudApplication;

import org.springframework.cloud.netflix.zuul.EnableZuulProxy;

import org.springframework.context.annotation.Bean;


import com.caituo.server.filter.MyZuulFilter;


@SpringCloudApplication

@EnableZuulProxy

@ServletComponentScan

public class ZuulApplication {

    public static void main(String[] args) {

        SpringApplication.run(ZuulApplication.class, args);

    }


    @Bean

    public MyZuulFilter getZuulFilter(){

        return new MyZuulFilter();

    }

}


当然还有其他高级用法,就具体问题具体分析了



5.MybatisGeneratorPlus生成器

目录结构如图

 

使用方法:

1.右键Pom.xml->Run As->Maven Install

 

2. 在template里面找着generatorConfig.xml。如图所示。

 

3. 然后编辑。

在这里改连接字符串。

<jdbcConnection driverClass="com.mysql.jdbc.Driver"

connectionURL="jdbc:mysql://10.66.1.32:3306/payment" 

userId="ssc"

password="ssc">

</jdbcConnection>


然后找着<table tableName=

然后编辑,复制,粘贴真个<table></table>标签

编辑成自己要的东东。

一般自己有几张表,就写复制粘贴几张表。


其余的别改,保存后。

Pom.xml->右键->Run As->Maven build…

 

复制下面命令进入Goals里面

-Dfile.encoding=UTF-8 -Dmybatis.generator.overwrite=true mybatis-generator:generate -e -X

点Run

 

好了,生成器会自动帮助生成Model, ModelExample, Mapper, Service, Controller. 包括@RequestMapping注解,swagger注释和文档。Cache的注解。


规范点:

1.Mysql里所有字段必须勾上非空。(暂缓推行)

如图所示。下面的软件是Navicat,如果用SqlYog软件也类似。

 

强制要求在插入字段时,必须设置一个值。




2. 所有的字段都要上索引,除了Blob字段。

 

3. 用mybatisGenerator生成器一次性生成所有代码,后期不允许自己写SQL语句。(暂缓推行)


有特殊要求比如join之类的跨表查询,用循环遍历来解决。


这样做好处:

1.把程序员从框架层面解放出来,专心实现业务代码。

2.各种数据表层面解耦。

3.提高代码可读性。

4.后期维护很容易。

5.把操作数据库变成操作对象一样容易。

6.后期做其他微服务改造很容易。


6.业务应用服务SpringBoot Server


目录结构如图所示:

 


 


6.1 服务启动方法:

@SpringBootApplication

@EnableCaching

@EnableScheduling

@EnableFeignClients(basePackages = "com.pay.api.client")

@ComponentScan(basePackages = "com.pay.api")

@ServletComponentScan

@EnableCircuitBreaker

@EnableHystrixDashboard

@EnableSwagger2

@EnableDiscoveryClient

public class Application {

public static void main(String[] args) {

SpringApplication.run(Application.class, args);

}

}


6.2 @EnableCaching

打开缓存标志, 打开之后,我们可以这么使用Cache

    @Cacheable(value = "cache:card", key = "'cache:card:get:id:'+#id")

    public Card get(Integer id) {

        return cardMapper.selectByPrimaryKey(id);

    }

    @CacheEvict(value = "cache:card", key = "'cache:card:get:id:'+#card.getId()")

    public Integer update(Card card) {

        return cardMapper.updateByPrimaryKeySelective(card);

    }

要求再pom里面配置:

<dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-cache</artifactId>

</dependency>


同时要实现2个类

@Component

public class RedisCacheManager implements CacheManager, DisposableBean {

@Autowired

@Qualifier("myRedisCache")

private Cache cache;

@Override

public void destroy() throws Exception {

cache.clear();

}

@Override

public Cache getCache(String name) {

return cache;

}

@Override

public Collection<String> getCacheNames() {

return null;

}

}


@Component("myRedisCache")

public class RedisCache implements Cache {

public static final Logger logger = LoggerFactory.getLogger(ShardedRedisCache.class);

……

@Override

public ValueWrapper get(Object key) {

//主要是在这里实现get方法

}

@Override

public void put(Object key, Object value) {

//主要在这里实现put方法

}

@Override

public <T> T get(Object key, Class<T> type) {

//主要是在这里实现get方法

}

@Override

public void evict(Object key) {

//主要在这里实现删除方法

}

……其余方法略

}


6.3 @EnableScheduling

打开Schedule标志

然后我们就可以在方法上面加上

@Scheduled(fixedRate = 1000)

来显式的声明这个方法是个定时任务。其余的高级表达式要具体情况具体分析

这个要在xml里面配置

<task:scheduler id="taskScheduler" pool-size="30" />

然后把xml加载进来

可以用如下方式加载

@Configuration

@ImportResource("classpath:/applicationContext.xml")

public class XmlConfiguration {

}

最后application.java上面要加上

@ComponentScan(basePackages = "com.pay.api")


6.4@EnableFeignClients(basePackages="com.pay.api.client")

意思是会扫描包com.pay.api.client下面的所有feign的远程调用代码

在这里声明了,就能够和在本地调用服务一样请求远程服务器了。

例如

@FeignClient(name = "tencentIMClient", url = "http://www.qq.com")

public interface TencentIMClient {

    @RequestMapping(method = {RequestMethod.POST}, value = {"/v4/openim/sendmsg"})

    String openimSendmsg(

        @RequestBody OpenimSendMsgRequest request,

        @RequestParam("identifier") String identifier,

        @RequestParam("sdkappid") int sdkAppId,

        @RequestParam("contenttype") String contentType,

        @RequestParam("random") int random,

        @RequestParam("usersig") String usersig

        );

}

注意,如果url没有指定,会去eureka服务器上面去查找name值的应用,然后访问后面对应的@RequestMapping对应的路径里的值

如果定义了url则是访问以url开头的网址

其中还可以指定一些其他的属性。


6.5 @ComponentScan(basePackages = "com.pay.api")

意思是扫描所有包名是com.pay.api下面的所有class,匹配所有AOP,注册成bean

6.6 @ServletComponentScan

在 SpringBootApplication 上使用@ServletComponentScan 注解后,Servlet、Filter、Listener 可以直接通过 @WebServlet、@WebFilter、@WebListener 注解自动注册,无需其他代码。

例如:

@WebServlet(urlPatterns="/xs/myservlet", description="Servlet的说明") 

public class MyServlet2 extends HttpServlet{ 

……

}

@WebServlet还有一个属性是name,在不指定name的情况下,name默认值为类全路径

再例如:用这个filter来解决跨域问题。

@WebFilter(filterName="corsFilter",urlPatterns="/*")

public class CorsFilter implements Filter{  

……

@Override

    public void doFilter(ServletRequest request, ServletResponse servletResponse,  

            FilterChain chain) throws IOException, ServletException {

            HttpServletResponse response = (HttpServletResponse) servletResponse;  

            response.setHeader("Access-Control-Allow-Origin", "*");

            response.setHeader("Access-Control-Allow-Methods", "POST, GET, OPTIONS, DELETE");  

            response.setHeader("Access-Control-Max-Age", "3600");

            response.setHeader("Access-Control-Allow-Headers", "Origin, X-Requested-With, Content-Type, Accept, token");  

            chain.doFilter(request, response);

    }  

其余的还有一些高级应用,要具体情况具体分析了

6.7 @EnableCircuitBreaker

这个是打开断路器的功能。

1. 引入Hystrix的依赖包

<dependency>

    <groupId>org.springframework.cloud</groupId>

    <artifactId>spring-cloud-starter-hystrix</artifactId>

</dependency>

2. bootstrap.yml中加上这个配置

#超时500毫秒, 基础服务运行超时。用于feign的中断

hystrix:

  command.default.execution.isolation.thread.timeoutInMilliseconds: 5000 //设置默认超时时间

  threadpool.default.coreSize: 50

  threadpool.default.maximumSize: 60

  threadpool.default.maxQueueSize: 40

#打开feign的断路器,可以在feign调用时使用超时熔断

feign:

  hystrix:

    enabled: true

3. 再要断路的地方上面加上这个AOP

@HystrixCommand(fallbackMethod = “fallback”, //要在同一个类里面写这个方法fallback(), 参数和返回对象要完全和下面的方法一致

commandProperties = {

@HystrixProperty(name = "execution.isolation.thread.timeoutInMilliseconds", value = "16666"),//超时时间

@HystrixProperty(name = "circuitBreaker.requestVolumeThreshold", value = "26"),//设置一个滑动窗口内触发熔断的最少请求量,默认20。

@HystrixProperty(name = "circuitBreaker.sleepWindowInMilliseconds", value = "6000") },//设置触发熔断后,拒绝请求后多长时间开始尝试再次执行。默认5000ms。

threadPoolProperties = {

@HystrixProperty(name = "coreSize", value = "10")})//设置线程池的core size,这是最大的并发执行数量。默认10

6.8 @EnableHystrixDashboard

运行Hystrix仪表板需要在spring boot主类上标注@EnableHystrixDashboard。然后访问/ hystrix查看仪表盘,在hystrix客户端应用使用/hystrix.stream监控。

 


6.9 @EnableDiscoveryClient

开启服务发现,自动往eureka服务器上注册自己的api来方便其他应用在eureka上查找相关服务。

需要在bootstrap.yml中配置

#打开eureka的注册查找地址

eureka:

  instance:

    lease-expiration-duration-in-seconds: 30

    lease-renewal-interval-in-seconds: 10

  client:

    serviceUrl:

      defaultZone: http://localhost:8761/eureka


6.10 @EnableSwagger2

通过注解EnableSwagger2声明Swagger的可用性。Swagger是一个规范和完整的框架,用于生成、描述、调用和可视化 RESTful 风格的 Web 服务。总体目标是使客户端和文件系统作为服务器以同样的速度来更新。文件的方法,参数和模型紧密集成到服务器端的代码,允许API来始终保持同步。步骤如下:

6.10.1. 添加maven依赖,需要在系统的pom中添加如下依赖:

<dependency>

   <groupId>io.springfox</groupId>

   <artifactId>springfox-swagger2</artifactId>

   <version>2.6.1</version>

</dependency>

<dependency>

   <groupId>io.springfox</groupId>

   <artifactId>springfox-swagger-ui</artifactId>

   <version>2.6.1</version>

</dependency>

6.10.2. 添加swagger配置文件,配置文件如下:

@Configuration

@EnableSwagger2

public class SwaggerConfig {

    @Bean

    public Docket api() {

        return new Docket(DocumentationType.SWAGGER_2)

                .select()  // 选择那些路径和api会生成document

                .apis(RequestHandlerSelectors.any()) // 对所有api进行监控或者可以用.apis(RequestHandlerSelectors.basePackage("com.fpfpp.server.controller"))

                .paths(PathSelectors.any()) // 对所有路径进行监控

                .build();

    }

}

6.10.3. 在Controller上面加

@Api(description = "增删改查列表Card")

@RestController

在方法上面加上@ApiOperation("查询Card")

在参数上面加上@ApiParam(value = "id")

示例如下:

@Api(description = "增删改查列表Card")

@RestController

@RequestMapping(value = "/v1/card", produces = MediaType.APPLICATION_JSON_UTF8_VALUE)

public class CardController implements Logging {

    public static final Logger logger = LoggerFactory.getLogger(CardController.class);

    @Autowired

    private CardService cardService;

    @ApiOperation("查询Card")

    @RequestMapping(value = "/{id}", method = RequestMethod.GET)

    public SimpleResponse get(@ApiParam(value = "id") @PathVariable Integer id) {

        return SimpleResponse.success(cardService.get(id));

    }

}

6.10.4最后查看swagger-ui

请访问http://hostname/rootpath/swagger-ui.html

 


7.注册中心服务Eureka Server

7.1 在pom.xml里添加依赖:

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-eureka-server</artifactId>

</dependency>

7.2 在bootstrap.yml里面配置如此:

server:

  port: 16661 #服务端口

spring:

  application:

    name: eureka-server

eureka:

  instance:

    preferIpAddress: true

    ipAddress: ${EUREKA_IPADDRESS:10.200.120.8}

    lease-renewal-interval-in-seconds: 6

    lease-expiration-duration-in-seconds: 6

    instanceId: ${spring.cloud.client.ipAddress}:${server.port}

  server:

    enable-self-preservation: false

    eviction-interval-timer-in-ms: 6666

  client:

    register-with-eureka: true #是否将eureka自身作为应用注册到eureka注册中心

    fetch-registry: true #为true时,可以启动,但报异常:Cannot execute request on any known server

    serviceUrl:

      defaultZone: ${EUREKA_DEFAULTZONE:http://10.200.120.8:16661/eureka/,http://10.200.110.8:16661/eureka/} 


7.3 EurekaServerApplication.java

最后应用程序是这么写,run起来就是一个eureka 服务器

上面的配置说明是个eureka集群。

@SpringBootApplication

@EnableEurekaServer

public class EurekaServerApplication {

    public static void main(String[] args) {

        SpringApplication.run(EurekaServerApplication.class, args);

    }

}


7.4 运行时界面如下

 


其他还有一些高级用法,就具体问题具体分析了


8.全链路监控服务Zipkin Server

8.1 pom.xml

<dependency>

      <groupId>org.springframework.cloud</groupId>

      <artifactId>spring-cloud-starter-eureka-server</artifactId>

</dependency>

<dependency>

      <groupId>io.zipkin.java</groupId>

      <artifactId>zipkin-server</artifactId>

</dependency>

<dependency>

      <groupId>io.zipkin.java</groupId>

      <artifactId>zipkin-autoconfigure-ui</artifactId>

</dependency>

<dependency>

<groupId>io.zipkin.java</groupId>

      <artifactId>zipkin-storage-mysql</artifactId>

      <version>1.19.0</version>

</dependency>

<dependency>

      <groupId>org.springframework.boot</groupId>

      <artifactId>spring-boot-starter-jdbc</artifactId>

</dependency>

<dependency>

      <groupId>mysql</groupId>

      <artifactId>mysql-connector-java</artifactId>

</dependency>


8.2 Bootstrap.yml

server:

  port: ${SERVER_PORT:16662}

spring:

  rabbitmq:

    host: ${RABBIT_HOST:localhost}

  datasource:

    url: jdbc:mysql://${SERVER_NAME:rm-uf637082fw6y68ufh.mysql.rds.aliyuncs.com}:${SERVER_PORT:3306}/${DATABASE_NAME:zipkin_91pay}

    username: ${MYSQL_USERNAME:payservice}

    password: ${MYSQL_PASSWORD:ADdKN0oZIQYH}

    # Switch this on to create the schema on startup:

    schema: classpath:/mysql.sql

    initialize: false

    continueOnError: true

  zipkin:

    base-url: http://${ZIPKIN_URL:10.200.110.8}:${ZIPKIN_PORT:16662}

  sleuth:

    enabled: true

zipkin:

  storage:

    type: mysql


8.3 ZipkinServerApplication.java

最后加上这几个,就跑起来就好了。

@SpringBootApplication

@EnableZipkinServer

public class ZipkinServerApplication {

    public static void main(String[] args) {

        SpringApplication.run(ZipkinServerApplication.class, args);

    }

    

    @Bean

    public MySQLStorage mySQLStorage(DataSource datasource) {

        return MySQLStorage.builder().datasource(datasource).executor(Runnable::run).build();

    }

    

}

8.4 客户端sleuth配置

然后客户端要使用zipkin server需要在bootstrap.yml配置里面加上。

bootstrap.yml

#zipkin

spring.zipkin.enabled=true

spring.zipkin.baseUrl=http://172.20.67.15:16662

spring.sleuth.sampler.percentage=0.1

Pom.xml里面加上

Pom.xml

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-sleuth</artifactId>

</dependency>

就可爽爽的使用sleuth往zipkin里面发数据啦。


8.5 运行时界面如下。

 


其他还有一些高级用法,就具体问题具体分析了


9.配置服务Config Server

9.1. Pom.xml

<dependencies>

    <dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-config-server</artifactId>

    </dependency>

    <dependency>

        <groupId>org.springframework.cloud</groupId>

        <artifactId>spring-cloud-starter-eureka</artifactId>

    </dependency>

</dependencies>


9.2. ConfigServerApplication.java

@SpringBootApplication

@EnableConfigServer

@EnableEurekaClient

@EnableAutoConfiguration

public class ConfigServerApplication {

public static void main(String[] args) {

SpringApplication.run(PayConfigServerApplication.class, args);

}

}


9.3. Config server 的yml的配置

server:

  port: 10663


eureka:

  client:

    serviceUrl:

      #eureka服务注册地址

      defaultZone: http://172.20.67.15:10661/eureka/


# git管理配置

spring:

  cloud:

    config:

      server:

        git:

          #git仓库地址

          uri: http://10.66.1.168:10080/91Pay/config-server

          #搜索路径配成变量,这样不同客户端会请求自己的目录名

          searchPaths: '{application}'

          username: wangfupeng@91steel.com

          password: Fff66p66p66p

  application:

    name: config-server

management:

  security:

enabled: false


如果有必要可以把config server配置到eureka上去也是支持的。



9.4. Client端的Pom.xml

<dependency>

<groupId>org.springframework.cloud</groupId>

<artifactId>spring-cloud-starter-config</artifactId>

</dependency>

9.5 Client端的在代码中的使用

在使用时用

@Value("${lucky-word}") 

String luckyWord;

把值注入进变量就好。


9.6 Client端的yml中的配置:

环境资源的命名规则由以下的三个参数确定:

{application}映射到Config客户端的spring.application.name属性

{profile}映射到Config客户端的spring.profiles.active属性,可以用来区分环境,比如dev,test,produce等等

{label}映射到Git服务器的commit id,分支名称或者tag,默认值为master

所以配置如下:

spring.application.name=accountServer

spring.profiles.active=dev

spring.cloud.config.label=master

spring.cloud.config.uri=http://localhost:8888

如果spring.cloud.config.uri没有配置,然后从eureka上面去发现config server也是可以的。

这样就是到configserver上的master分支上的accountServer目录里面的accountServer-dev.yml上面去找资料了。


其他还有一些高级用法,就具体问题具体分析了


10.各种命名规范

10.1变量命名规范。


强制要求所有变量命名用类名首字母小写,然后在后面加上适当含义 。

比如

JedisPool jedisPool 合规

JedisPool jedisPoolForAccountServer. 合规


JedisPool hcc     不合规


10.2 强制要求所有魔法值全部用KeyCommon这个类里的属性来替代。

比如.andIsAdminEqualTo(true).andStatusEqualTo("40");

要改成

.andIsAdminEqualTo(true).andStatusEqualTo(KeyCommon.STATUS_COMPLETE_VERIFY);

然后在KeyCommon里面写一个

public static final String STATUS_COMPLETE_VERIFY = "40";


10.3 所有抛出的异常在TemplateErrorCode里面定义。

 


使用方式用throw new 

TemplateException(TemplateErrorCode.LIMIT_PROGRAM_AOP_PREFERENCE_ERROR);

在要抛出异常的地方抛出异常即可。


10.4 方法名命名规范

用有意义的英文单词来做命名。遵从驼峰标志。



11. 模板使用方法

11.1 从git上面下载代码,查看章节2。

 


11.2用STS打开。STS下载地址在http://spring.io/tools/sts

 

下载后,解压缩。运行STS.exe


11.3 配置好maven和jdk

 


 


Maven的Settings.xml配置如下

已经删除了无用的注释和没有用的组件。

<?xml version="1.0" encoding="UTF-8"?>

<settings xmlns="http://maven.apache.org/SETTINGS/1.0.0"

          xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"

          xsi:schemaLocation="http://maven.apache.org/SETTINGS/1.0.0 http://maven.apache.org/xsd/settings-1.0.0.xsd">

  <localRepository>c:/java/maven/repository6</localRepository>

  <pluginGroups>

  </pluginGroups>

  <servers>

  </servers> 

  <proxies>

  </proxies>

  <mirrors>

    <mirror>

      <id>Fff666666</id>

      <mirrorOf>central</mirrorOf>

      <name>Maven Repository Caituo</name>

      <url>http://10.66.1.40:8081/nexus/content/groups/public/</url>

    </mirror>

  </mirrors>

  <profiles>

    <profile>

      <id>caituo</id>

      <repositories>

        <repository>

          <id>caituo</id>

          <name>Caituo Repositories Group</name>

          <url>http://10.66.1.40:8081/nexus/content/groups/public/</url>

 <snapshots>

<enabled>true</enabled>

 </snapshots>

        </repository>

      </repositories>

    </profile>

  </profiles>

  <activeProfiles>

    <activeProfile>caituo</activeProfile>

  </activeProfiles>

</settings>


 


11.3 导入template源码

 


 


 


Maven Update一下下载相应的jar包。

只要你配的nexus服务器是10.66.1.40. 能确保加载成功,没有报异常。

 


 


11.4 重命名模板里面的文件夹名称或者更改目录结构,改成自己要的包名。

 


11.5 把com.caituo.template替换成自己的包名。

 


要全部都替换。

 


 



11.6 启动方法

开发时的启动方法就时Application.java->右键->Debug As->Java Application


 


在服务器上面启动方法是:

1. 先maven install成一个jar包假设名字叫zzzzzz-66601.jar

2. 在secureCRT用sz命令上传至服务器。如果没有sz可以用yum install lrzsz安装。

3. 用这个命令运行起来就好了。

nohup java –jar zzzzzz-66601.jar –-ENV=prod >/dev/null &

如果java没有找着,可以带上java的全路径。


12.附上之前做的一整套架构。

 


其中有几个不足:


1. Redis版本低2.8.7,没法做Cluster,如果用redis cluster(版本3.0+)就可以不用shardedJedisPool。其实差不多。


2. ElasticSearch对大数据量查询(返回数据10000条+)支持很差。对小数据量查询(返回数据100条以内)支持非常好。


13.阿里巴巴的P3C标准

13.1. P3C标准的pdf文档

 


13.2.P3C的Eclipse插件安装办法及启动检查

1. Help->Install New Software

 

输入https://p3c.alibaba.com/plugin/eclipse/update, 按回车,选中插件,

点Next->Next->I Accept -> Finish

 

 

 

重启STS

再右键选中项目。会出来一个

 


点击开始扫描。

扫描结果在P3C Results里面有

 

要把所有的提示全部清除掉

更改时在当前STS里改会很慢,建议再起一个没有装P3C的STS来改。

P3C只是在扫描代码时使用。


网友评论

登录后评论
0/500
评论
王伏芃
+ 关注