Commit dc4df86396b43c3102c87e5272274200a6f67c45
1 parent
6f262f5b
Exists in
master
优化定时服务和片网络图片映射
Showing
37 changed files
with
1588 additions
and
132 deletions
Show diff stats
cloud/.gitignore
cloud/common/src/main/java/com/sincere/common/util/BaiduApiUtiols.java
@@ -1,84 +0,0 @@ | @@ -1,84 +0,0 @@ | ||
1 | -package com.sincere.common.util; | ||
2 | - | ||
3 | -import org.springframework.http.HttpEntity; | ||
4 | -import org.springframework.http.HttpHeaders; | ||
5 | -import org.springframework.http.MediaType; | ||
6 | -import org.springframework.http.ResponseEntity; | ||
7 | -import org.springframework.util.LinkedMultiValueMap; | ||
8 | -import org.springframework.util.MultiValueMap; | ||
9 | -import org.springframework.web.client.RestTemplate; | ||
10 | - | ||
11 | -public class BaiduApiUtiols { | ||
12 | - | ||
13 | - public static BaiduApiUtiols baiduApiUtiols; | ||
14 | - | ||
15 | - public static BaiduApiUtiols getInstance() { | ||
16 | - | ||
17 | - if (null == baiduApiUtiols) { | ||
18 | - synchronized (BaiduApiUtiols.class) { | ||
19 | - baiduApiUtiols = new BaiduApiUtiols(); | ||
20 | - } | ||
21 | - } | ||
22 | - return baiduApiUtiols; | ||
23 | - } | ||
24 | - | ||
25 | - | ||
26 | - /** | ||
27 | - * @param imgPath 图片路径 | ||
28 | - * @param group_id 学校id | ||
29 | - * @param user_id 用户id | ||
30 | - * @param user_info 用户名字 | ||
31 | - * @return | ||
32 | - */ | ||
33 | - public String registerFace(String imgPath, String group_id, String user_id, String user_info) { | ||
34 | - | ||
35 | - String registUrl = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=" + AuthService.getFaceAuthToken(); | ||
36 | - long time = System.currentTimeMillis(); | ||
37 | - System.out.println("starttime:"+time); | ||
38 | - RestTemplate restTemplate = new RestTemplate(); | ||
39 | - MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>(); | ||
40 | - multiValueMap.add("image", Base64Util.imageencode(imgPath)); | ||
41 | - multiValueMap.add("image_type", "BASE64"); | ||
42 | - multiValueMap.add("group_id", group_id); | ||
43 | - multiValueMap.add("user_id", user_id); | ||
44 | - multiValueMap.add("user_info", user_info); | ||
45 | -// multiValueMap.add("quality_control", "NORMAL"); | ||
46 | - System.out.println("multiValueMap:" + multiValueMap.toString()); | ||
47 | - HttpHeaders headers = new HttpHeaders(); | ||
48 | - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
49 | - HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(multiValueMap, | ||
50 | - headers); | ||
51 | - System.out.println("midddle:"+(System.currentTimeMillis()-time)); | ||
52 | - time = System.currentTimeMillis(); | ||
53 | - ResponseEntity<String> result = restTemplate.postForEntity(registUrl, requestEntity, String.class); | ||
54 | - System.out.println("end:"+(System.currentTimeMillis()-time)); | ||
55 | - System.out.println("result:" + result.getBody()); | ||
56 | - return result.getBody(); | ||
57 | - | ||
58 | - } | ||
59 | - | ||
60 | - public String searchFace(String imgPath,String group_id, String user_id){ | ||
61 | - String searchFace = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token="+AuthService.getFaceAuthToken(); | ||
62 | - long time = System.currentTimeMillis(); | ||
63 | - RestTemplate restTemplate = new RestTemplate(); | ||
64 | - MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>(); | ||
65 | - multiValueMap.add("image", Base64Util.imageencode(imgPath)); | ||
66 | - multiValueMap.add("image_type", "BASE64"); | ||
67 | - multiValueMap.add("group_id_list", group_id);//从指定的group中进行查找 用逗号分隔,上限10个 | ||
68 | - multiValueMap.add("user_id", user_id);//当需要对特定用户进行比对时,指定user_id进行比对。即人脸认证功能。 | ||
69 | -// multiValueMap.add("quality_control", "NORMAL"); | ||
70 | - System.out.println("multiValueMap:" + multiValueMap.toString()); | ||
71 | - HttpHeaders headers = new HttpHeaders(); | ||
72 | - headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
73 | - HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(multiValueMap, | ||
74 | - headers); | ||
75 | - System.out.println("midddle:"+(System.currentTimeMillis()-time)); | ||
76 | - time = System.currentTimeMillis(); | ||
77 | - ResponseEntity<String> result = restTemplate.postForEntity(searchFace, requestEntity, String.class); | ||
78 | - System.out.println("end:"+(System.currentTimeMillis()-time)); | ||
79 | - System.out.println("result:" + result.getBody()); | ||
80 | - return result.getBody(); | ||
81 | - | ||
82 | - } | ||
83 | - | ||
84 | -} |
cloud/common/src/main/java/com/sincere/common/util/HttpClientUtils.java
@@ -40,17 +40,17 @@ public class HttpClientUtils { | @@ -40,17 +40,17 @@ public class HttpClientUtils { | ||
40 | requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build(); | 40 | requestConfig = RequestConfig.custom().setSocketTimeout(5000).setConnectTimeout(5000).build(); |
41 | } | 41 | } |
42 | 42 | ||
43 | - public static void main(String[] args){ | ||
44 | -// String url = "http://http://zhktest.114school.com.cn/szkjapi/toyxy/addTeacherOrg" ; | ||
45 | -// String json = "{\"name\": \"子部门\",\"groupname\": \"父部门\",\"schoolid\": \"16\",\"token\": \"05719991\"}" ; | ||
46 | -// JSONObject jsonObject = HttpClientUtils.httpPostJson(url,json); | 43 | +// public static void main(String[] args){ |
44 | +//// String url = "http://http://zhktest.114school.com.cn/szkjapi/toyxy/addTeacherOrg" ; | ||
45 | +//// String json = "{\"name\": \"子部门\",\"groupname\": \"父部门\",\"schoolid\": \"16\",\"token\": \"05719991\"}" ; | ||
46 | +//// JSONObject jsonObject = HttpClientUtils.httpPostJson(url,json); | ||
47 | +//// System.out.println(jsonObject.toJSONString()); | ||
48 | +// | ||
49 | +// String url = "http://campus.myjxt.com/api/Room/GetListPageRoom" ; | ||
50 | +// String json = "PageIndex=1&roomId=6583&pageSize=9999" ; | ||
51 | +// JSONObject jsonObject = HttpClientUtils.httpPost(url,json); | ||
47 | // System.out.println(jsonObject.toJSONString()); | 52 | // System.out.println(jsonObject.toJSONString()); |
48 | - | ||
49 | - String url = "http://campus.myjxt.com/api/Room/GetListPageRoom" ; | ||
50 | - String json = "PageIndex=1&roomId=6583&pageSize=9999" ; | ||
51 | - JSONObject jsonObject = HttpClientUtils.httpPost(url,json); | ||
52 | - System.out.println(jsonObject.toJSONString()); | ||
53 | - } | 53 | +// } |
54 | 54 | ||
55 | /** | 55 | /** |
56 | * post请求传输json参数 | 56 | * post请求传输json参数 |
@@ -0,0 +1,48 @@ | @@ -0,0 +1,48 @@ | ||
1 | +<?xml version="1.0" encoding="UTF-8"?> | ||
2 | +<project xmlns="http://maven.apache.org/POM/4.0.0" | ||
3 | + xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" | ||
4 | + xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd"> | ||
5 | + <parent> | ||
6 | + <artifactId>cloud</artifactId> | ||
7 | + <groupId>com.sincere</groupId> | ||
8 | + <version>1.0.0</version> | ||
9 | + </parent> | ||
10 | + <modelVersion>4.0.0</modelVersion> | ||
11 | + | ||
12 | + <artifactId>fIle-center</artifactId> | ||
13 | + | ||
14 | + <description>文件中心</description> | ||
15 | + | ||
16 | + <properties> | ||
17 | + <swagger-version>2.9.2</swagger-version> | ||
18 | + </properties> | ||
19 | + | ||
20 | + | ||
21 | + <dependencies> | ||
22 | + | ||
23 | + <dependency> | ||
24 | + <groupId>io.springfox</groupId> | ||
25 | + <artifactId>springfox-swagger-ui</artifactId> | ||
26 | + <version>${swagger-version}</version> | ||
27 | + </dependency> | ||
28 | + <dependency> | ||
29 | + <groupId>io.springfox</groupId> | ||
30 | + <artifactId>springfox-swagger2</artifactId> | ||
31 | + <version>${swagger-version}</version> | ||
32 | + </dependency> | ||
33 | + | ||
34 | + <!-- WEB守护进程启动springboot --> | ||
35 | + <dependency> | ||
36 | + <groupId>org.springframework.boot</groupId> | ||
37 | + <artifactId>spring-boot-starter-web</artifactId> | ||
38 | + </dependency> | ||
39 | + | ||
40 | + <dependency> | ||
41 | + <groupId>com.aliyun.oss</groupId> | ||
42 | + <artifactId>aliyun-sdk-oss</artifactId> | ||
43 | + <version>2.8.3</version> | ||
44 | + </dependency> | ||
45 | + | ||
46 | + </dependencies> | ||
47 | + | ||
48 | +</project> | ||
0 | \ No newline at end of file | 49 | \ No newline at end of file |
cloud/fIle-center/src/main/java/com/sincere/file/FileApplication.java
0 → 100644
@@ -0,0 +1,15 @@ | @@ -0,0 +1,15 @@ | ||
1 | +package com.sincere.file; | ||
2 | + | ||
3 | +import org.springframework.boot.SpringApplication; | ||
4 | +import org.springframework.boot.autoconfigure.SpringBootApplication; | ||
5 | +import org.springframework.cloud.client.discovery.EnableDiscoveryClient; | ||
6 | +import org.springframework.cloud.netflix.eureka.EnableEurekaClient; | ||
7 | + | ||
8 | +@EnableDiscoveryClient | ||
9 | +@SpringBootApplication | ||
10 | +public class FileApplication { | ||
11 | + | ||
12 | + public static void main(String[] args) { | ||
13 | + SpringApplication.run(FileApplication.class,args); | ||
14 | + } | ||
15 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/config/AliyunOSSConfig.java
0 → 100644
@@ -0,0 +1,36 @@ | @@ -0,0 +1,36 @@ | ||
1 | +package com.sincere.file.config; | ||
2 | + | ||
3 | +import com.aliyun.oss.OSSClient; | ||
4 | +import org.springframework.beans.factory.annotation.Value; | ||
5 | +import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty; | ||
6 | +import org.springframework.context.annotation.Bean; | ||
7 | +import org.springframework.context.annotation.Configuration; | ||
8 | + | ||
9 | + | ||
10 | +/** | ||
11 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
12 | + * @version 创建时间:2018年1月31日 下午9:11:36 类说明 白名单 | ||
13 | + * 阿里云配置 | ||
14 | + */ | ||
15 | +@Configuration | ||
16 | +public class AliyunOSSConfig { | ||
17 | + | ||
18 | + @Value("${aliyun.oss.endpoint:xxxxx}") | ||
19 | + private String endpoint; | ||
20 | + @Value("${aliyun.oss.access-key:xxxxx}") | ||
21 | + private String accessKeyId; | ||
22 | + @Value("${aliyun.oss.accessKeySecret:xxxxx}") | ||
23 | + private String accessKeySecret; | ||
24 | + | ||
25 | + /** | ||
26 | + * 阿里云文件存储client | ||
27 | + * 只有配置了aliyun.oss.access-key才可以使用 | ||
28 | + */ | ||
29 | + @Bean | ||
30 | + @ConditionalOnProperty(name = "aliyun.oss.access-key", matchIfMissing = true) | ||
31 | + public OSSClient ossClient() { | ||
32 | + OSSClient ossClient = new OSSClient(endpoint, accessKeyId, accessKeySecret); | ||
33 | + return ossClient; | ||
34 | + } | ||
35 | + | ||
36 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/config/SwaggerConfig.java
0 → 100644
@@ -0,0 +1,89 @@ | @@ -0,0 +1,89 @@ | ||
1 | +package com.sincere.file.config; | ||
2 | + | ||
3 | +import org.springframework.context.MessageSource; | ||
4 | +import org.springframework.context.annotation.Bean; | ||
5 | +import org.springframework.context.annotation.Configuration; | ||
6 | +import org.springframework.context.support.ResourceBundleMessageSource; | ||
7 | +import org.springframework.stereotype.Component; | ||
8 | +import org.springframework.web.servlet.ViewResolver; | ||
9 | +import org.springframework.web.servlet.config.annotation.DefaultServletHandlerConfigurer; | ||
10 | +import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry; | ||
11 | +import org.springframework.web.servlet.config.annotation.WebMvcConfigurer; | ||
12 | +import org.springframework.web.servlet.view.InternalResourceViewResolver; | ||
13 | +import org.springframework.web.servlet.view.JstlView; | ||
14 | +import springfox.documentation.builders.ApiInfoBuilder; | ||
15 | +import springfox.documentation.builders.ParameterBuilder; | ||
16 | +import springfox.documentation.builders.PathSelectors; | ||
17 | +import springfox.documentation.builders.RequestHandlerSelectors; | ||
18 | +import springfox.documentation.schema.ModelRef; | ||
19 | +import springfox.documentation.service.ApiInfo; | ||
20 | +import springfox.documentation.service.Parameter; | ||
21 | +import springfox.documentation.spi.DocumentationType; | ||
22 | +import springfox.documentation.spring.web.plugins.Docket; | ||
23 | +import springfox.documentation.swagger2.annotations.EnableSwagger2; | ||
24 | + | ||
25 | +import java.util.ArrayList; | ||
26 | +import java.util.List; | ||
27 | + | ||
28 | +@Component | ||
29 | +@Configuration | ||
30 | +@EnableSwagger2 | ||
31 | +public class SwaggerConfig implements WebMvcConfigurer { | ||
32 | + | ||
33 | + @Bean | ||
34 | + public Docket createRestApi() { | ||
35 | + | ||
36 | + | ||
37 | + ParameterBuilder tokenPar = new ParameterBuilder(); | ||
38 | + List<Parameter> pars = new ArrayList<>(); | ||
39 | + tokenPar.name("ossPath").description("OSS存储路径,例如: YikeData"). | ||
40 | + modelRef(new ModelRef("string")). | ||
41 | + parameterType("header").required(false).build(); | ||
42 | + | ||
43 | + pars.add(tokenPar.build()); | ||
44 | + | ||
45 | + return new Docket(DocumentationType.SWAGGER_2).apiInfo(apiInfo()).select() | ||
46 | + .apis(RequestHandlerSelectors.basePackage("com.sincere.file.control")) | ||
47 | +// .apis(RequestHandlerSelectors.any()) | ||
48 | +// .paths( input ->PathSelectors.regex("/file/*").apply(input) || PathSelectors.regex("/fileinfo.*").apply(input) | ||
49 | +// ) | ||
50 | + .paths(PathSelectors.any()) | ||
51 | + .build().globalOperationParameters(pars); | ||
52 | + } | ||
53 | + | ||
54 | + private ApiInfo apiInfo() { | ||
55 | + return new ApiInfoBuilder().title("文件中心api").description("文件中心api").version("1.0").build(); | ||
56 | + } | ||
57 | + | ||
58 | + @Bean | ||
59 | + public ViewResolver viewResolver() { | ||
60 | + InternalResourceViewResolver resolver = new InternalResourceViewResolver(); | ||
61 | + resolver.setViewClass(JstlView.class); | ||
62 | + resolver.setPrefix("/"); | ||
63 | + resolver.setSuffix(".html"); | ||
64 | + return resolver; | ||
65 | + | ||
66 | + } | ||
67 | + | ||
68 | + @Bean | ||
69 | + public MessageSource messageSource() { | ||
70 | + ResourceBundleMessageSource messageSource = new ResourceBundleMessageSource(); | ||
71 | + messageSource.setBasename("messages"); | ||
72 | + return messageSource; | ||
73 | + } | ||
74 | + | ||
75 | + @Override | ||
76 | + public void addResourceHandlers(ResourceHandlerRegistry registry) { | ||
77 | +// super.addResourceHandlers(registry); | ||
78 | + registry.addResourceHandler("swagger-ui.html").addResourceLocations("classpath:/META-INF/resources/"); | ||
79 | + registry.addResourceHandler("/webjars/**").addResourceLocations("classpath:/META-INF/resources/webjars/"); | ||
80 | + } | ||
81 | + | ||
82 | + @Override | ||
83 | + public void configureDefaultServletHandling(DefaultServletHandlerConfigurer configurer) { | ||
84 | + configurer.enable(); | ||
85 | + } | ||
86 | + | ||
87 | + | ||
88 | + | ||
89 | +} | ||
0 | \ No newline at end of file | 90 | \ No newline at end of file |
cloud/fIle-center/src/main/java/com/sincere/file/control/FileControl.java
0 → 100644
@@ -0,0 +1,42 @@ | @@ -0,0 +1,42 @@ | ||
1 | +package com.sincere.file.control; | ||
2 | + | ||
3 | +import com.sincere.file.model.FileInfo; | ||
4 | +import com.sincere.file.service.FileService; | ||
5 | +import com.sincere.file.utils.FileUtil; | ||
6 | +import io.swagger.annotations.Api; | ||
7 | +import io.swagger.annotations.ApiOperation; | ||
8 | +import org.springframework.beans.factory.annotation.Autowired; | ||
9 | +import org.springframework.web.bind.annotation.*; | ||
10 | +import org.springframework.web.multipart.MultipartFile; | ||
11 | + | ||
12 | +import javax.servlet.http.HttpServletRequest; | ||
13 | + | ||
14 | +@RestController | ||
15 | +@Api(tags = "文件管理") | ||
16 | +@RequestMapping(value = "file/*") | ||
17 | +public class FileControl { | ||
18 | + | ||
19 | + @Autowired | ||
20 | + FileService fileService; | ||
21 | + | ||
22 | + @PostMapping("fileUpload") | ||
23 | + @ApiOperation("上传文件") | ||
24 | + public String fileUpload(@RequestParam("file") MultipartFile file, HttpServletRequest request) throws Exception { | ||
25 | + | ||
26 | + String ossPath = request.getHeader("ossPath");//oss的二级目录 | ||
27 | + | ||
28 | + FileInfo fileInfo = fileService.upload(file, ossPath); | ||
29 | + | ||
30 | + return fileInfo.getUrl(); | ||
31 | + | ||
32 | + } | ||
33 | + | ||
34 | + | ||
35 | + @DeleteMapping("deleteFile/{fileName}") | ||
36 | + @ApiOperation("删除文件") | ||
37 | + public boolean deleteFile(@PathVariable String fileName,HttpServletRequest request){ | ||
38 | + String ossPath = request.getHeader("ossPath");//oss的二级目录 | ||
39 | + fileService.delete(fileName,ossPath); | ||
40 | + return true; | ||
41 | + } | ||
42 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/model/FileInfo.java
0 → 100644
@@ -0,0 +1,39 @@ | @@ -0,0 +1,39 @@ | ||
1 | +package com.sincere.file.model; | ||
2 | + | ||
3 | +import lombok.Data; | ||
4 | + | ||
5 | +import java.io.Serializable; | ||
6 | +import java.util.Date; | ||
7 | + | ||
8 | +/** | ||
9 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
10 | + * @version 创建时间:2017年11月12日 上午22:57:51 | ||
11 | + * file实体类 | ||
12 | +*/ | ||
13 | +@Data | ||
14 | +public class FileInfo implements Serializable { | ||
15 | + | ||
16 | + private static final long serialVersionUID = -1438078028040922174L; | ||
17 | +// md5字段 | ||
18 | + private String id; | ||
19 | +// 原始文件名 | ||
20 | + private String name; | ||
21 | +// 是否图片 | ||
22 | + private Boolean isImg; | ||
23 | +// 上传文件类型 | ||
24 | + private String contentType; | ||
25 | +// 文件大小 | ||
26 | + private long size; | ||
27 | +// 冗余字段 | ||
28 | + private String path; | ||
29 | +// oss访问路径 oss需要设置公共读 | ||
30 | + private String url; | ||
31 | +// FileType字段 | ||
32 | + private String source; | ||
33 | + private Date createTime; | ||
34 | + /** | ||
35 | + * 目录磁盘地址 | ||
36 | + */ | ||
37 | +// @TableField(exist = false) | ||
38 | +// private String pathDir; | ||
39 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/service/FileService.java
0 → 100644
@@ -0,0 +1,24 @@ | @@ -0,0 +1,24 @@ | ||
1 | +package com.sincere.file.service; | ||
2 | + | ||
3 | +import com.sincere.file.model.FileInfo; | ||
4 | +import org.springframework.web.multipart.MultipartFile; | ||
5 | + | ||
6 | +import java.util.Map; | ||
7 | + | ||
8 | +/** | ||
9 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
10 | + * @version 创建时间:2017年11月12日 上午22:57:51 | ||
11 | + * 文件service 目前仅支持阿里云oss,七牛云 | ||
12 | +*/ | ||
13 | +public interface FileService { | ||
14 | + | ||
15 | + FileInfo upload(MultipartFile file,String filePath) throws Exception; | ||
16 | + | ||
17 | + void delete(String fileName,String filePath); | ||
18 | + | ||
19 | + FileInfo getById(String id); | ||
20 | + | ||
21 | +// PageResult<FileInfo> findList(Map<String, Object> params); | ||
22 | + | ||
23 | + void unZip(String filePath, String descDir) throws RuntimeException ; | ||
24 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/service/impl/AbstractFileService.java
0 → 100644
@@ -0,0 +1,88 @@ | @@ -0,0 +1,88 @@ | ||
1 | +package com.sincere.file.service.impl; | ||
2 | + | ||
3 | +import com.sincere.file.model.FileInfo; | ||
4 | +import com.sincere.file.service.FileService; | ||
5 | +import com.sincere.file.utils.FileUtil; | ||
6 | +import lombok.extern.slf4j.Slf4j; | ||
7 | +import org.springframework.web.multipart.MultipartFile; | ||
8 | + | ||
9 | +import java.util.concurrent.ExecutorService; | ||
10 | +import java.util.concurrent.Executors; | ||
11 | + | ||
12 | +/** | ||
13 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
14 | + * @version 创建时间:2017年11月12日 上午22:57:51 | ||
15 | + * AbstractFileService 抽取类 | ||
16 | + * 根据filetype 实例化具体oss对象 | ||
17 | +*/ | ||
18 | +@Slf4j | ||
19 | +public abstract class AbstractFileService implements FileService { | ||
20 | + | ||
21 | +// protected abstract FileDao getFileDao(); | ||
22 | + protected static ExecutorService executorService = Executors.newFixedThreadPool(Runtime.getRuntime().availableProcessors()); | ||
23 | + @Override | ||
24 | + public FileInfo upload(MultipartFile file,String filePath) throws Exception { | ||
25 | + FileInfo fileInfo = FileUtil.getFileInfo(file); | ||
26 | +// FileInfo oldFileInfo = getFileDao().getById(fileInfo.getId()); | ||
27 | +// if (oldFileInfo != null) { | ||
28 | +// return oldFileInfo; | ||
29 | +// } | ||
30 | +// | ||
31 | +// if (!fileInfo.getName().contains(".")) { | ||
32 | +// throw new IllegalArgumentException("缺少后缀名"); | ||
33 | +// } | ||
34 | + | ||
35 | + uploadFile(file, fileInfo,filePath); | ||
36 | + | ||
37 | +// fileInfo.setSource(fileType().name());// 设置文件来源 | ||
38 | +// getFileDao().save(fileInfo);// 将文件信息保存到数据库 | ||
39 | +// // 本地保存文件 | ||
40 | +// FileUtil.saveFile(file,fileInfo.getPath()); | ||
41 | +// log.info("上传文件:{}", fileInfo); | ||
42 | + | ||
43 | + return fileInfo; | ||
44 | + } | ||
45 | + | ||
46 | + /** | ||
47 | + * 上传文件 | ||
48 | + * | ||
49 | + * @param file | ||
50 | + * @param fileInfo | ||
51 | + */ | ||
52 | + protected abstract void uploadFile(MultipartFile file, FileInfo fileInfo,String filePath) throws Exception; | ||
53 | + | ||
54 | + @Override | ||
55 | + public void delete(String fileName,String filePath) { | ||
56 | + deleteFile(fileName,filePath); | ||
57 | +// getFileDao().delete(fileInfo.getId()); | ||
58 | + log.info("删除文件:{}", fileName); | ||
59 | + } | ||
60 | + | ||
61 | + /** | ||
62 | + * 删除文件资源 | ||
63 | + * | ||
64 | +// * @param fileInfo | ||
65 | + * @return | ||
66 | + */ | ||
67 | + protected abstract boolean deleteFile(String fileName,String filePath); | ||
68 | + | ||
69 | + @Override | ||
70 | + public FileInfo getById(String id){ | ||
71 | +// return getFileDao().getById(id); | ||
72 | + return null; | ||
73 | + } | ||
74 | + | ||
75 | +// public PageResult<FileInfo> findList(Map<String, Object> params){ | ||
76 | +// //设置分页信息,分别是当前页数和每页显示的总记录数【记住:必须在mapper接口中的方法执行之前设置该分页信息】 | ||
77 | +// PageHelper.startPage(MapUtils.getInteger(params, "page"),MapUtils.getInteger(params, "limit"),true); | ||
78 | +// | ||
79 | +// List<FileInfo> list = getFileDao().findList(params); | ||
80 | +// PageInfo<FileInfo> pageInfo = new PageInfo<>(list); | ||
81 | +// return PageResult.<FileInfo>builder().data(pageInfo.getList()).code(0).count(pageInfo.getTotal()).build(); | ||
82 | +// } | ||
83 | + | ||
84 | + @Override | ||
85 | + public void unZip(String filePath, String descDir) throws RuntimeException { | ||
86 | + | ||
87 | + } | ||
88 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/service/impl/AliyunOssServiceImpl.java
0 → 100644
@@ -0,0 +1,51 @@ | @@ -0,0 +1,51 @@ | ||
1 | +package com.sincere.file.service.impl; | ||
2 | + | ||
3 | +import com.aliyun.oss.OSSClient; | ||
4 | +import com.sincere.file.model.FileInfo; | ||
5 | +import org.springframework.beans.factory.annotation.Autowired; | ||
6 | +import org.springframework.beans.factory.annotation.Value; | ||
7 | +import org.springframework.stereotype.Service; | ||
8 | +import org.springframework.web.multipart.MultipartFile; | ||
9 | + | ||
10 | +/** | ||
11 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
12 | + * @version 创建时间:2017年11月12日 上午22:57:51 | ||
13 | +* 阿里云oss存储文件 | ||
14 | +*/ | ||
15 | +@Service("aliyunOssServiceImpl") | ||
16 | +public class AliyunOssServiceImpl extends AbstractFileService { | ||
17 | + | ||
18 | +// @Autowired | ||
19 | +// private FileDao fileDao; | ||
20 | + | ||
21 | +// @Override | ||
22 | +// protected FileDao getFileDao() { | ||
23 | +// return fileDao; | ||
24 | +// } | ||
25 | + | ||
26 | +// @Override | ||
27 | +// protected FileType fileType() { | ||
28 | +// return FileType.ALIYUN; | ||
29 | +// } | ||
30 | + | ||
31 | + @Autowired | ||
32 | + private OSSClient ossClient; | ||
33 | + | ||
34 | + @Value("${aliyun.oss.bucketName:xxxxx}") | ||
35 | + private String bucketName; | ||
36 | + @Value("${aliyun.oss.domain:xxxxx}") | ||
37 | + private String domain; | ||
38 | + | ||
39 | + @Override | ||
40 | + protected void uploadFile(MultipartFile file, FileInfo fileInfo,String filePath) throws Exception { | ||
41 | + ossClient.putObject(bucketName, filePath+"/"+fileInfo.getName(), file.getInputStream()); | ||
42 | + fileInfo.setUrl(domain + "/" + fileInfo.getName()); | ||
43 | + } | ||
44 | + | ||
45 | + @Override | ||
46 | + protected boolean deleteFile(String fileName,String filePath) { | ||
47 | + ossClient.deleteObject(bucketName,filePath+"/"+ fileName); | ||
48 | + return true; | ||
49 | + } | ||
50 | + | ||
51 | +} |
cloud/fIle-center/src/main/java/com/sincere/file/utils/FileUtil.java
0 → 100644
@@ -0,0 +1,88 @@ | @@ -0,0 +1,88 @@ | ||
1 | +package com.sincere.file.utils; | ||
2 | + | ||
3 | +import com.sincere.file.model.FileInfo; | ||
4 | +import lombok.extern.slf4j.Slf4j; | ||
5 | +import org.apache.commons.codec.digest.DigestUtils; | ||
6 | +import org.springframework.web.multipart.MultipartFile; | ||
7 | + | ||
8 | +import java.io.File; | ||
9 | +import java.io.IOException; | ||
10 | +import java.io.InputStream; | ||
11 | +import java.util.Date; | ||
12 | + | ||
13 | +/** | ||
14 | + * @author 作者 owen E-mail: 624191343@qq.com | ||
15 | + * @version 创建时间:2017年11月12日 上午22:57:51 | ||
16 | + * 文件工具类 | ||
17 | +*/ | ||
18 | +@Slf4j | ||
19 | +public class FileUtil { | ||
20 | + | ||
21 | + public static FileInfo getFileInfo(MultipartFile file) throws Exception { | ||
22 | + String md5 = fileMd5(file.getInputStream()); | ||
23 | + | ||
24 | + FileInfo fileInfo = new FileInfo(); | ||
25 | + fileInfo.setId(md5);// 将文件的md5设置为文件表的id | ||
26 | + fileInfo.setName(file.getOriginalFilename()); | ||
27 | + fileInfo.setContentType(file.getContentType()); | ||
28 | + fileInfo.setIsImg(fileInfo.getContentType().startsWith("image/")); | ||
29 | + fileInfo.setSize(file.getSize()); | ||
30 | + fileInfo.setCreateTime(new Date()); | ||
31 | + | ||
32 | + return fileInfo; | ||
33 | + } | ||
34 | + | ||
35 | + /** | ||
36 | + * 文件的md5 | ||
37 | + * | ||
38 | + * @param inputStream | ||
39 | + * @return | ||
40 | + */ | ||
41 | + public static String fileMd5(InputStream inputStream) { | ||
42 | + try { | ||
43 | + return DigestUtils.md5Hex(inputStream); | ||
44 | + } catch (IOException e) { | ||
45 | + log.error("FileUtil->fileMd5:{}" ,e.getMessage()); | ||
46 | + } | ||
47 | + | ||
48 | + return null; | ||
49 | + } | ||
50 | + | ||
51 | + public static String saveFile(MultipartFile file, String path) { | ||
52 | + try { | ||
53 | + File targetFile = new File(path); | ||
54 | + if (targetFile.exists()) { | ||
55 | + return path; | ||
56 | + } | ||
57 | + | ||
58 | + if (!targetFile.getParentFile().exists()) { | ||
59 | + targetFile.getParentFile().mkdirs(); | ||
60 | + } | ||
61 | + file.transferTo(targetFile); | ||
62 | + | ||
63 | + return path; | ||
64 | + } catch (Exception e) { | ||
65 | + log.error("FileUtil->saveFile:{}" ,e.getMessage()); | ||
66 | + } | ||
67 | + | ||
68 | + return null; | ||
69 | + } | ||
70 | + | ||
71 | + public static boolean deleteFile(String pathname) { | ||
72 | + File file = new File(pathname); | ||
73 | + if (file.exists()) { | ||
74 | + boolean flag = file.delete(); | ||
75 | + | ||
76 | + if (flag) { | ||
77 | + File[] files = file.getParentFile().listFiles(); | ||
78 | + if (files == null || files.length == 0) { | ||
79 | + file.getParentFile().delete(); | ||
80 | + } | ||
81 | + } | ||
82 | + | ||
83 | + return flag; | ||
84 | + } | ||
85 | + | ||
86 | + return false; | ||
87 | + } | ||
88 | +} |
@@ -0,0 +1,181 @@ | @@ -0,0 +1,181 @@ | ||
1 | +#阿里云文件上传 | ||
2 | +aliyun: | ||
3 | + oss: | ||
4 | + access-key: QiuM3PwHTnVotcGy | ||
5 | + accessKeySecret: Yqs7RlaC1MioZu2YYJ6u0TdeO13VFC | ||
6 | + endpoint: http://oss-cn-hangzhou.aliyuncs.com | ||
7 | + bucketName: szyundisk | ||
8 | + domain: https://szyundisk.oss-cn-hangzhou.aliyuncs.com | ||
9 | +##七牛文件上传 | ||
10 | +#qiniu: | ||
11 | +# oss: | ||
12 | +# access-key: owGiAWGn6DpU5zlrfLP4K9iQusahmspTW6PxRABW | ||
13 | +# accessKeySecret: 5CBWKFd1pP-OSiusd1Bvhokp-ih4i3bs2QA2r-U2 | ||
14 | +# endpoint: http://q4c5xw7eb.bkt.clouddn.com | ||
15 | +# bucketName: ocpowenwangwen | ||
16 | +## 本地文件上传 | ||
17 | +#file: | ||
18 | +# oss: | ||
19 | +# domain: http://127.0.0.1:9200/api-file | ||
20 | +# path: d:/uploadshp | ||
21 | +# prefix: /statics | ||
22 | + | ||
23 | +#fastDFS配置 | ||
24 | +#fdfs: | ||
25 | +# oss : | ||
26 | +# ##nginx需要安装fastdfs插件 | ||
27 | +# domain: http://192.168.235.173/ | ||
28 | +# soTimeout: 1500 | ||
29 | +# connectTimeout: 600 | ||
30 | +# pool: | ||
31 | +# jmx-enabled: false | ||
32 | +# trackerList: 192.168.235.173:22122 | ||
33 | + | ||
34 | + | ||
35 | +#spring: | ||
36 | +# datasource: | ||
37 | +# dynamic: | ||
38 | +# enable: true | ||
39 | +# druid: | ||
40 | +# # JDBC 配置(驱动类自动从url的mysql识别,数据源类型自动识别) | ||
41 | +# core: | ||
42 | +# url: jdbc:mysql://localhost:3306/file_center?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false | ||
43 | +# username: root | ||
44 | +# password: 123456 | ||
45 | +# driver-class-name: com.mysql.cj.jdbc.Driver | ||
46 | +# log: | ||
47 | +# url: jdbc:mysql://localhost:3306/log_center?useUnicode=true&characterEncoding=utf-8&allowMultiQueries=true&useSSL=false | ||
48 | +# username: root | ||
49 | +# password: 123456 | ||
50 | +# driver-class-name: com.mysql.cj.jdbc.Driver | ||
51 | +# #连接池配置(通常来说,只需要修改initialSize、minIdle、maxActive | ||
52 | +# initial-size: 1 | ||
53 | +# max-active: 20 | ||
54 | +# min-idle: 1 | ||
55 | +# # 配置获取连接等待超时的时间 | ||
56 | +# max-wait: 60000 | ||
57 | +# #打开PSCache,并且指定每个连接上PSCache的大小 | ||
58 | +# pool-prepared-statements: true | ||
59 | +# max-pool-prepared-statement-per-connection-size: 20 | ||
60 | +# validation-query: SELECT 'x' | ||
61 | +# test-on-borrow: false | ||
62 | +# test-on-return: false | ||
63 | +# test-while-idle: true | ||
64 | +# #配置间隔多久才进行一次检测,检测需要关闭的空闲连接,单位是毫秒 | ||
65 | +# time-between-eviction-runs-millis: 60000 | ||
66 | +# #配置一个连接在池中最小生存的时间,单位是毫秒 | ||
67 | +# min-evictable-idle-time-millis: 300000 | ||
68 | +# filters: stat,wall | ||
69 | +# # WebStatFilter配置,说明请参考Druid Wiki,配置_配置WebStatFilter | ||
70 | +# #是否启用StatFilter默认值true | ||
71 | +# web-stat-filter.enabled: true | ||
72 | +# web-stat-filter.url-pattern: /* | ||
73 | +# web-stat-filter.exclusions: "*.js , *.gif ,*.jpg ,*.png ,*.css ,*.ico , /druid/*" | ||
74 | +# web-stat-filter.session-stat-max-count: 1000 | ||
75 | +# web-stat-filter.profile-enable: true | ||
76 | +# # StatViewServlet配置 | ||
77 | +# #展示Druid的统计信息,StatViewServlet的用途包括:1.提供监控信息展示的html页面2.提供监控信息的JSON API | ||
78 | +# #是否启用StatViewServlet默认值true | ||
79 | +# stat-view-servlet.enabled: true | ||
80 | +# #根据配置中的url-pattern来访问内置监控页面,如果是上面的配置,内置监控页面的首页是/druid/index.html例如: | ||
81 | +# #http://110.76.43.235:9000/druid/index.html | ||
82 | +# #http://110.76.43.235:8080/mini-web/druid/index.html | ||
83 | +# stat-view-servlet.url-pattern: /druid/* | ||
84 | +# #允许清空统计数据 | ||
85 | +# stat-view-servlet.reset-enable: true | ||
86 | +# stat-view-servlet.login-username: admin | ||
87 | +# stat-view-servlet.login-password: admin | ||
88 | +# #StatViewSerlvet展示出来的监控信息比较敏感,是系统运行的内部情况,如果你需要做访问控制,可以配置allow和deny这两个参数 | ||
89 | +# #deny优先于allow,如果在deny列表中,就算在allow列表中,也会被拒绝。如果allow没有配置或者为空,则允许所有访问 | ||
90 | +# #配置的格式 | ||
91 | +# #<IP> | ||
92 | +# #或者<IP>/<SUB_NET_MASK_size>其中128.242.127.1/24 | ||
93 | +# #24表示,前面24位是子网掩码,比对的时候,前面24位相同就匹配,不支持IPV6。 | ||
94 | +# #stat-view-servlet.allow= | ||
95 | +# #stat-view-servlet.deny=128.242.127.1/24,128.242.128.1 | ||
96 | +# # Spring监控配置,说明请参考Druid Github Wiki,配置_Druid和Spring关联监控配置 | ||
97 | +# #aop-patterns= # Spring监控AOP切入点,如x.y.z.service.*,配置多个英文逗号分隔 | ||
98 | +#################### mysq end ########################## | ||
99 | +## zipkin: | ||
100 | +## base-url: http://127.0.0.1:11008 | ||
101 | +# redis: | ||
102 | +#################### redis 单机版 start ########################## | ||
103 | +# host: 127.0.0.1 | ||
104 | +# port: 6379 | ||
105 | +# timeout: 6000 | ||
106 | +# database: 1 | ||
107 | +# lettuce: | ||
108 | +# pool: | ||
109 | +# max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽) | ||
110 | +# max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8 | ||
111 | +# max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException | ||
112 | +# min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0 | ||
113 | +# shutdown-timeout: 100ms | ||
114 | +#################### redis 单机版 end ########################## | ||
115 | +## cluster: | ||
116 | +## 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 | ||
117 | +## #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 | ||
118 | +## #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 | ||
119 | +## timeout: 1000 # 连接超时时间(毫秒) | ||
120 | +## lettuce: | ||
121 | +## pool: | ||
122 | +## max-active: 10 # 连接池最大连接数(使用负值表示没有限制),如果赋值为-1,则表示不限制;如果pool已经分配了maxActive个jedis实例,则此时pool的状态为exhausted(耗尽) | ||
123 | +## max-idle: 8 # 连接池中的最大空闲连接 ,默认值也是8 | ||
124 | +## max-wait: 100 # # 等待可用连接的最大时间,单位毫秒,默认值为-1,表示永不超时。如果超过等待时间,则直接抛出JedisConnectionException | ||
125 | +## min-idle: 2 # 连接池中的最小空闲连接 ,默认值也是0 | ||
126 | +## shutdown-timeout: 100ms | ||
127 | +# | ||
128 | +##mybatis: | ||
129 | +#mybatis-plus: | ||
130 | +# configuration: | ||
131 | +# log-impl: org.apache.ibatis.logging.stdout.StdOutImpl | ||
132 | +# config-location: classpath:mybatis.cfg.xml | ||
133 | +# mapper-locations: classpath*:com/open/**/dao/*.xml | ||
134 | +# | ||
135 | +# | ||
136 | +#security: | ||
137 | +# oauth2: | ||
138 | +# ignored: /files-anon/** , /doc.html ,/upload.html , /uploads.html ,/js/** ,/document.html | ||
139 | +# token: | ||
140 | +# store: | ||
141 | +# type: redis | ||
142 | + | ||
143 | + | ||
144 | +#设置最大超时时间 | ||
145 | +ribbon: | ||
146 | + httpclient: | ||
147 | + enabled: false | ||
148 | + okhttp: | ||
149 | + enabled: true | ||
150 | + ReadTimeout: 90000 | ||
151 | + ConnectTimeout: 90000 | ||
152 | + OkToRetryOnAllOperations: true | ||
153 | + MaxAutoRetries: 1 | ||
154 | + MaxAutoRetriesNextServer: 1 | ||
155 | + | ||
156 | + | ||
157 | +#设置最大容错超时时间 | ||
158 | +hystrix: | ||
159 | + command: | ||
160 | + default: | ||
161 | + execution: | ||
162 | + timeout: | ||
163 | + enabled: true | ||
164 | + isolation: | ||
165 | + thread: | ||
166 | + timeoutInMilliseconds: 90000 | ||
167 | + | ||
168 | + | ||
169 | + | ||
170 | +#logging: | ||
171 | +# level: | ||
172 | +# com.open.capacity: INFO | ||
173 | +# org.hibernate: INFO | ||
174 | +# org.hibernate.type.descriptor.sql.BasicBinder: TRACE | ||
175 | +# org.hibernate.type.descriptor.sql.BasicExtractor: TRACE | ||
176 | +# com.neusoft: DEBUG | ||
177 | +# com.netflix: DEBUG #用于心跳检测输出的日志 | ||
178 | + | ||
179 | + | ||
180 | + | ||
181 | + | ||
0 | \ No newline at end of file | 182 | \ No newline at end of file |
@@ -0,0 +1,41 @@ | @@ -0,0 +1,41 @@ | ||
1 | +#端口 | ||
2 | +server: | ||
3 | + port: 5000 #固定端口 | ||
4 | +# port: ${randomServerPort.value[5000,5005]} #随机端口 | ||
5 | + | ||
6 | +#服务名称 | ||
7 | +spring: | ||
8 | + application: | ||
9 | + name: file-center | ||
10 | + servlet: | ||
11 | + multipart: | ||
12 | + max-request-size: 400MB | ||
13 | + max-file-size: 400MB | ||
14 | + | ||
15 | +management: | ||
16 | + endpoints: | ||
17 | + web: | ||
18 | + exposure: | ||
19 | + include: "*" | ||
20 | + endpoint: | ||
21 | + health: | ||
22 | + show-details: always | ||
23 | + | ||
24 | +#eureka client配置 | ||
25 | +eureka: | ||
26 | + client: | ||
27 | + serviceUrl: | ||
28 | + defaultZone: http://localhost:8761/eureka/,http://localhost:8762/eureka/ | ||
29 | + #http://134.224.249.33:1111/eureka/ 正式库 | ||
30 | + #http://134.224.249.33:1111/eureka/ 测试库 | ||
31 | + #http://127.0.0.1:8761/eureka,http://127.0.0.1:8762/eureka | ||
32 | + registry-fetch-interval-seconds: 5 | ||
33 | + instance-info-replication-interval-seconds: 10 | ||
34 | + instance: | ||
35 | + prefer-ip-address: true | ||
36 | + instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}} #固定端口 | ||
37 | +# instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${randomServerPort.value[5000,5005]}} #随机端口 | ||
38 | + lease-renewal-interval-in-seconds: 10 #每隔几秒告诉eureka服务器我还存活,用于心跳检测 | ||
39 | + lease-expiration-duration-in-seconds: 10 #如果心跳检测一直没有发送,10秒后会从eureka服务器中将此服务剔除 | ||
40 | + status-page-url: http://${spring.cloud.client.ip-address}:${server.port}/doc.html # ${server.port}为该服务的端口号 | ||
41 | +# status-page-url: http://${spring.cloud.client.ip-address}:${randomServerPort.value[5000,5005]}/document.html # ${server.port}为该服务的端口号 | ||
0 | \ No newline at end of file | 42 | \ No newline at end of file |
cloud/geteway/src/main/resources/application.yml
@@ -10,6 +10,7 @@ eureka: | @@ -10,6 +10,7 @@ eureka: | ||
10 | lease-expiration-duration-in-seconds: 90 | 10 | lease-expiration-duration-in-seconds: 90 |
11 | lease-renewal-interval-in-seconds: 10 | 11 | lease-renewal-interval-in-seconds: 10 |
12 | prefer-ip-address: true | 12 | prefer-ip-address: true |
13 | + instance-id: ${spring.application.name}:${spring.cloud.client.ip-address}:${spring.application.instance_id:${server.port}} #固定端口 | ||
13 | 14 | ||
14 | spring: | 15 | spring: |
15 | cloud: | 16 | cloud: |
@@ -21,3 +22,9 @@ spring: | @@ -21,3 +22,9 @@ spring: | ||
21 | - Path=/haikangserver/** | 22 | - Path=/haikangserver/** |
22 | filters: | 23 | filters: |
23 | - StripPrefix=1 | 24 | - StripPrefix=1 |
25 | + - id: file-center | ||
26 | + uri: lb://file-center | ||
27 | + predicates: | ||
28 | + - Path=/file-center/** | ||
29 | + filters: | ||
30 | + - StripPrefix=1 | ||
24 | \ No newline at end of file | 31 | \ No newline at end of file |
cloud/geteway/src/test/java/com/example/geteway/GetewayApplicationTests.java
@@ -1,16 +0,0 @@ | @@ -1,16 +0,0 @@ | ||
1 | -package com.example.geteway; | ||
2 | - | ||
3 | -import org.junit.Test; | ||
4 | -import org.junit.runner.RunWith; | ||
5 | -import org.springframework.boot.test.context.SpringBootTest; | ||
6 | -import org.springframework.test.context.junit4.SpringRunner; | ||
7 | - | ||
8 | -@RunWith(SpringRunner.class) | ||
9 | -@SpringBootTest | ||
10 | -public class GetewayApplicationTests { | ||
11 | - | ||
12 | - @Test | ||
13 | - public void contextLoads() { | ||
14 | - } | ||
15 | - | ||
16 | -} |
cloud/haikangface/src/main/java/com/sincere/haikangface/control/UserControl.java
1 | package com.sincere.haikangface.control; | 1 | package com.sincere.haikangface.control; |
2 | 2 | ||
3 | -import com.netflix.ribbon.proxy.annotation.Http; | ||
4 | import com.sincere.common.dto.smartCampus.SZ_AttendanceDto; | 3 | import com.sincere.common.dto.smartCampus.SZ_AttendanceDto; |
5 | -import com.sincere.common.util.BaiduApiUtiols; | 4 | +import com.sincere.haikangface.utils.BaiduApiUtiols; |
6 | import com.sincere.haikangface.CMSServer; | 5 | import com.sincere.haikangface.CMSServer; |
7 | import com.sincere.haikangface.async.SendUserAsync; | 6 | import com.sincere.haikangface.async.SendUserAsync; |
8 | import com.sincere.haikangface.bean.StudentBean; | 7 | import com.sincere.haikangface.bean.StudentBean; |
@@ -23,10 +22,8 @@ import org.springframework.web.bind.annotation.RequestMethod; | @@ -23,10 +22,8 @@ import org.springframework.web.bind.annotation.RequestMethod; | ||
23 | import org.springframework.web.bind.annotation.RequestParam; | 22 | import org.springframework.web.bind.annotation.RequestParam; |
24 | import org.springframework.web.bind.annotation.RestController; | 23 | import org.springframework.web.bind.annotation.RestController; |
25 | import org.springframework.web.multipart.MultipartFile; | 24 | import org.springframework.web.multipart.MultipartFile; |
26 | -import sun.rmi.runtime.Log; | ||
27 | 25 | ||
28 | import java.io.*; | 26 | import java.io.*; |
29 | -import java.math.BigInteger; | ||
30 | import java.text.SimpleDateFormat; | 27 | import java.text.SimpleDateFormat; |
31 | import java.util.Calendar; | 28 | import java.util.Calendar; |
32 | import java.util.Date; | 29 | import java.util.Date; |
cloud/haikangface/src/main/java/com/sincere/haikangface/utils/BaiduApiUtiols.java
0 → 100644
@@ -0,0 +1,86 @@ | @@ -0,0 +1,86 @@ | ||
1 | +package com.sincere.haikangface.utils; | ||
2 | + | ||
3 | +import com.sincere.common.util.AuthService; | ||
4 | +import com.sincere.common.util.Base64Util; | ||
5 | +import org.springframework.http.HttpEntity; | ||
6 | +import org.springframework.http.HttpHeaders; | ||
7 | +import org.springframework.http.MediaType; | ||
8 | +import org.springframework.http.ResponseEntity; | ||
9 | +import org.springframework.util.LinkedMultiValueMap; | ||
10 | +import org.springframework.util.MultiValueMap; | ||
11 | +import org.springframework.web.client.RestTemplate; | ||
12 | + | ||
13 | +public class BaiduApiUtiols { | ||
14 | + | ||
15 | + public static BaiduApiUtiols baiduApiUtiols; | ||
16 | + | ||
17 | + public static BaiduApiUtiols getInstance() { | ||
18 | + | ||
19 | + if (null == baiduApiUtiols) { | ||
20 | + synchronized (BaiduApiUtiols.class) { | ||
21 | + baiduApiUtiols = new BaiduApiUtiols(); | ||
22 | + } | ||
23 | + } | ||
24 | + return baiduApiUtiols; | ||
25 | + } | ||
26 | + | ||
27 | + | ||
28 | + /** | ||
29 | + * @param imgPath 图片路径 | ||
30 | + * @param group_id 学校id | ||
31 | + * @param user_id 用户id | ||
32 | + * @param user_info 用户名字 | ||
33 | + * @return | ||
34 | + */ | ||
35 | + public String registerFace(String imgPath, String group_id, String user_id, String user_info) { | ||
36 | + | ||
37 | + String registUrl = "https://aip.baidubce.com/rest/2.0/face/v3/faceset/user/add?access_token=" + AuthService.getFaceAuthToken(); | ||
38 | + long time = System.currentTimeMillis(); | ||
39 | + System.out.println("starttime:"+time); | ||
40 | + RestTemplate restTemplate = new RestTemplate(); | ||
41 | + MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>(); | ||
42 | + multiValueMap.add("image", Base64Util.imageencode(imgPath)); | ||
43 | + multiValueMap.add("image_type", "BASE64"); | ||
44 | + multiValueMap.add("group_id", group_id); | ||
45 | + multiValueMap.add("user_id", user_id); | ||
46 | + multiValueMap.add("user_info", user_info); | ||
47 | +// multiValueMap.add("quality_control", "NORMAL"); | ||
48 | + System.out.println("multiValueMap:" + multiValueMap.toString()); | ||
49 | + HttpHeaders headers = new HttpHeaders(); | ||
50 | + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
51 | + HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(multiValueMap, | ||
52 | + headers); | ||
53 | + System.out.println("midddle:"+(System.currentTimeMillis()-time)); | ||
54 | + time = System.currentTimeMillis(); | ||
55 | + ResponseEntity<String> result = restTemplate.postForEntity(registUrl, requestEntity, String.class); | ||
56 | + System.out.println("end:"+(System.currentTimeMillis()-time)); | ||
57 | + System.out.println("result:" + result.getBody()); | ||
58 | + return result.getBody(); | ||
59 | + | ||
60 | + } | ||
61 | + | ||
62 | + public String searchFace(String imgPath,String group_id, String user_id){ | ||
63 | + String searchFace = "https://aip.baidubce.com/rest/2.0/face/v3/search?access_token="+AuthService.getFaceAuthToken(); | ||
64 | + long time = System.currentTimeMillis(); | ||
65 | + RestTemplate restTemplate = new RestTemplate(); | ||
66 | + MultiValueMap<String, String> multiValueMap = new LinkedMultiValueMap<>(); | ||
67 | + multiValueMap.add("image", Base64Util.imageencode(imgPath)); | ||
68 | + multiValueMap.add("image_type", "BASE64"); | ||
69 | + multiValueMap.add("group_id_list", group_id);//从指定的group中进行查找 用逗号分隔,上限10个 | ||
70 | + multiValueMap.add("user_id", user_id);//当需要对特定用户进行比对时,指定user_id进行比对。即人脸认证功能。 | ||
71 | +// multiValueMap.add("quality_control", "NORMAL"); | ||
72 | + System.out.println("multiValueMap:" + multiValueMap.toString()); | ||
73 | + HttpHeaders headers = new HttpHeaders(); | ||
74 | + headers.setContentType(MediaType.APPLICATION_FORM_URLENCODED); | ||
75 | + HttpEntity<MultiValueMap> requestEntity = new HttpEntity<MultiValueMap>(multiValueMap, | ||
76 | + headers); | ||
77 | + System.out.println("midddle:"+(System.currentTimeMillis()-time)); | ||
78 | + time = System.currentTimeMillis(); | ||
79 | + ResponseEntity<String> result = restTemplate.postForEntity(searchFace, requestEntity, String.class); | ||
80 | + System.out.println("end:"+(System.currentTimeMillis()-time)); | ||
81 | + System.out.println("result:" + result.getBody()); | ||
82 | + return result.getBody(); | ||
83 | + | ||
84 | + } | ||
85 | + | ||
86 | +} |
cloud/pom.xml
@@ -41,7 +41,8 @@ | @@ -41,7 +41,8 @@ | ||
41 | <!-- <module>weigeng</module>--> | 41 | <!-- <module>weigeng</module>--> |
42 | <!-- <module>independence</module>--> | 42 | <!-- <module>independence</module>--> |
43 | <!-- <module>quartz</module>--> | 43 | <!-- <module>quartz</module>--> |
44 | - <!-- <module>zkAttendance</module>--> | 44 | + <module>zkAttendance</module> |
45 | + <module>fIle-center</module> | ||
45 | </modules> | 46 | </modules> |
46 | 47 | ||
47 | <dependencies> | 48 | <dependencies> |
@@ -90,7 +91,12 @@ | @@ -90,7 +91,12 @@ | ||
90 | <artifactId>commons-io</artifactId> | 91 | <artifactId>commons-io</artifactId> |
91 | <version>2.6</version> | 92 | <version>2.6</version> |
92 | </dependency> | 93 | </dependency> |
93 | - | 94 | + <dependency> |
95 | + <groupId>org.springframework.boot</groupId> | ||
96 | + <artifactId>spring-boot-starter-test</artifactId> | ||
97 | + <scope>test</scope> | ||
98 | + <version>2.0.2.RELEASE</version> | ||
99 | + </dependency> | ||
94 | </dependencies> | 100 | </dependencies> |
95 | 101 | ||
96 | <dependencyManagement> | 102 | <dependencyManagement> |
@@ -118,4 +124,23 @@ | @@ -118,4 +124,23 @@ | ||
118 | </dependency> | 124 | </dependency> |
119 | </dependencies> | 125 | </dependencies> |
120 | </dependencyManagement> | 126 | </dependencyManagement> |
127 | + | ||
128 | + <!-- 形成带第三方jar包的可执行jar包,jar包目录结构如下 application.properties lib META-INF mybatis | ||
129 | + org --> | ||
130 | + <build> | ||
131 | + <plugins> | ||
132 | + <plugin> | ||
133 | + <groupId>org.springframework.boot</groupId> | ||
134 | + <artifactId>spring-boot-maven-plugin</artifactId> | ||
135 | + <!--<executions> | ||
136 | + <execution> | ||
137 | + <goals> | ||
138 | + <goal>repackage</goal> | ||
139 | + </goals> | ||
140 | + </execution> | ||
141 | + </executions>--> | ||
142 | + </plugin> | ||
143 | + </plugins> | ||
144 | + <finalName>${project.artifactId}</finalName> | ||
145 | + </build> | ||
121 | </project> | 146 | </project> |
cloud/server1/src/main/java/com/sincere/server1/listener/EurekaInstanceCanceledListener.java
0 → 100644
@@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
1 | +package com.sincere.server1.listener; | ||
2 | + | ||
3 | + | ||
4 | +import com.netflix.discovery.shared.Applications; | ||
5 | +import com.netflix.eureka.EurekaServerContextHolder; | ||
6 | +import com.netflix.eureka.registry.PeerAwareInstanceRegistry; | ||
7 | +import lombok.extern.slf4j.Slf4j; | ||
8 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; | ||
9 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; | ||
10 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent; | ||
11 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent; | ||
12 | +import org.springframework.context.ApplicationEvent; | ||
13 | +import org.springframework.context.ApplicationListener; | ||
14 | +import org.springframework.context.annotation.Configuration; | ||
15 | + | ||
16 | +/** | ||
17 | + * 用于监听eureka服务停机通知 | ||
18 | + * Created by ace on 2017/7/8. | ||
19 | + */ | ||
20 | +@Slf4j | ||
21 | +@Configuration | ||
22 | +public class EurekaInstanceCanceledListener implements ApplicationListener { | ||
23 | + @Override | ||
24 | + public void onApplicationEvent(ApplicationEvent applicationEvent) { | ||
25 | + // 服务挂掉事件 | ||
26 | + if (applicationEvent instanceof EurekaInstanceCanceledEvent) { | ||
27 | + EurekaInstanceCanceledEvent event = (EurekaInstanceCanceledEvent) applicationEvent; | ||
28 | + // 获取当前Eureka实例中的节点信息 | ||
29 | + PeerAwareInstanceRegistry registry = EurekaServerContextHolder.getInstance().getServerContext().getRegistry(); | ||
30 | + Applications applications = registry.getApplications(); | ||
31 | + // 遍历获取已注册节点中与当前失效节点ID一致的节点信息 | ||
32 | + applications.getRegisteredApplications().forEach((registeredApplication) -> { | ||
33 | + registeredApplication.getInstances().forEach((instance) -> { | ||
34 | + if (instance.getInstanceId().equals(event.getServerId())) { | ||
35 | + log.debug("服务:" + instance.getAppName() + " 挂啦。。。"); | ||
36 | + // // TODO: 2017/9/3 扩展消息提醒 邮件、手机短信、微信等 | ||
37 | + } | ||
38 | + }); | ||
39 | + }); | ||
40 | + | ||
41 | + | ||
42 | + } | ||
43 | + if (applicationEvent instanceof EurekaInstanceRegisteredEvent) { | ||
44 | + EurekaInstanceRegisteredEvent event = (EurekaInstanceRegisteredEvent) applicationEvent; | ||
45 | + log.debug("服务:" + event.getInstanceInfo().getAppName() + " 注册成功啦。。。"); | ||
46 | + } | ||
47 | + if (applicationEvent instanceof EurekaInstanceRenewedEvent) { | ||
48 | + EurekaInstanceRenewedEvent event = (EurekaInstanceRenewedEvent) applicationEvent; | ||
49 | + log.debug("心跳检测服务:" + event.getInstanceInfo().getAppName() + "。。"); | ||
50 | + } | ||
51 | + if (applicationEvent instanceof EurekaRegistryAvailableEvent) { | ||
52 | + log.debug("服务 Aualiable。。"); | ||
53 | + } | ||
54 | + | ||
55 | + } | ||
56 | + | ||
57 | + | ||
58 | +} | ||
59 | + |
cloud/server1/src/main/resources/application.yaml
@@ -9,22 +9,28 @@ spring: | @@ -9,22 +9,28 @@ spring: | ||
9 | 9 | ||
10 | eureka: | 10 | eureka: |
11 | instance: | 11 | instance: |
12 | - preferIpAddress: true | ||
13 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 | 12 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 |
14 | lease-renewal-interval-in-seconds: 10 | 13 | lease-renewal-interval-in-seconds: 10 |
15 | lease-expiration-duration-in-seconds: 60 | 14 | lease-expiration-duration-in-seconds: 60 |
16 | - | ||
17 | hostname: localhost | 15 | hostname: localhost |
16 | + prefer-ip-address: true | ||
18 | server: | 17 | server: |
19 | #是否开启保护模式 | 18 | #是否开启保护模式 |
20 | - enable-self-preservation: true | ||
21 | - eviction-interval-timer-in-ms: 4000 | 19 | + enable-self-preservation: false #关闭服务器自我保护,客户端心跳检测15分钟内错误达到80%服务会保护,导致别人还认为是好用的服务 |
20 | + eviction-interval-timer-in-ms: 4000 #清理间隔(单位毫秒,默认是60*1000)5秒将客户端剔除的服务在服务注册列表中剔除# | ||
22 | #当进入保护模式的情况下,注册中心不会注销服务,以兼容分区故障 | 21 | #当进入保护模式的情况下,注册中心不会注销服务,以兼容分区故障 |
23 | - renewal-percent-threshold: 0.5 | 22 | + renewal-percent-threshold: 0.5 # 指定每分钟需要收到的续约次数的阈值,默认值就是:0.85 |
23 | + response-cache-update-interval-ms: 3000 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上默认30s | ||
24 | + response-cache-auto-expiration-in-seconds: 180 #eureka server缓存readWriteCacheMap失效时间,这个只有在这个时间过去后缓存才会失效,失效前不会更新,过期后从registry重新读取注册服务信息,registry是一个ConcurrentHashMap。 | ||
24 | client: | 25 | client: |
25 | #是否注册eureka,高可用的清况下使用 | 26 | #是否注册eureka,高可用的清况下使用 |
26 | - register-with-eureka: true | 27 | + register-with-eureka: true #false:不作为一个客户端注册到注册中心,是否将自身的实例信息注册到eureka服务器 |
27 | #是否启用获取服务注册信息 | 28 | #是否启用获取服务注册信息 |
28 | - fetch-registry: true | 29 | + fetch-registry: false #为true时,可以启动,但报异常:Cannot execute request on any known server ,是否从eureka服务端获取注册信息,消费者需要配置true |
30 | + instance-info-replication-interval-seconds: 10 | ||
31 | + registry-fetch-interval-seconds: 30 #从eureka服务端获取注册信息的间隔时间 | ||
29 | service-url: | 32 | service-url: |
30 | - defaultZone: http://localhost:8762/eureka/ | ||
31 | \ No newline at end of file | 33 | \ No newline at end of file |
34 | + defaultZone: http://localhost:8762/eureka/ | ||
35 | + | ||
36 | +ribbon: | ||
37 | + ServerListRefreshInterval: 1000 #刷新服务列表源的间隔时间 |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<nav class="navbar navbar-default" role="navigation" > | ||
3 | + <div class="container"> | ||
4 | + <div class="navbar-header"> | ||
5 | + <a class="navbar-brand" href="<@spring.url dashboardPath/>"><span></span></a> | ||
6 | + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | ||
7 | + <span class="sr-only">切换导航</span> | ||
8 | + <span class="icon-bar"></span> | ||
9 | + <span class="icon-bar"></span> | ||
10 | + <span class="icon-bar"></span> | ||
11 | + </button> | ||
12 | + </div> | ||
13 | + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | ||
14 | + <ul class="nav navbar-nav navbar-right"> | ||
15 | + <li> | ||
16 | + <a href="<@spring.url dashboardPath/>">主页</a> | ||
17 | + </li> | ||
18 | + <li> | ||
19 | + <a href="<@spring.url dashboardPath/>/lastn">最近启动的1000个服务</a> | ||
20 | + </li> | ||
21 | + </ul> | ||
22 | + </div> | ||
23 | + </div> | ||
24 | +</nav> | ||
25 | + | ||
26 | + |
@@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<!doctype html> | ||
3 | +<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | ||
4 | +<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | ||
5 | +<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | ||
6 | +<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | ||
7 | + <head> | ||
8 | + <base href="<@spring.url basePath/>"> | ||
9 | + <title>注册中心-事件</title> | ||
10 | + <link rel="stylesheet" type="text/css" href="eureka/css/wro.css"> | ||
11 | + </head> | ||
12 | + <body id="three"> | ||
13 | + | ||
14 | + <!--[if lt IE 7]> | ||
15 | + <p>您使用的是旧版本的浏览器。请升级您的浏览器以改善您的体验。</p> | ||
16 | + <![endif]--> | ||
17 | + | ||
18 | + <#include "header.ftl"> | ||
19 | + | ||
20 | + <div class="container-fluid xd-container"> | ||
21 | + <#include "navbar.ftl"> | ||
22 | + | ||
23 | + <div id="xd-jobs" class="tab-pane active col-md-12"> | ||
24 | + <ul class="nav nav-tabs" role="tablist" id="myTab"> | ||
25 | + <li class="active"><a data-toggle="tab" href="#cancelled">最后1000个取消的租约</a></li> | ||
26 | + <li><a data-toggle="tab" href="#registered">最近1000份新注册租约</a></li> | ||
27 | + </ul> | ||
28 | + <div class="tab-content"> | ||
29 | + <div class="tab-pane" id="cancelled"> | ||
30 | + <table id='lastNCanceled' class="table table-striped table-hover"> | ||
31 | + <thead> | ||
32 | + <tr><th>租约</th><th>时间戳</th></tr> | ||
33 | + </thead> | ||
34 | + <tbody> | ||
35 | + <#if lastNCanceled?has_content> | ||
36 | + <#list lastNCanceled as entry> | ||
37 | + <tr><td>${entry.date?datetime}</td><td>${entry.id}</td></tr> | ||
38 | + </#list> | ||
39 | + <#else> | ||
40 | + <tr><td colspan="2">没有可用的资源</td></tr> | ||
41 | + </#if> | ||
42 | + <tbody> | ||
43 | + </table> | ||
44 | + </div> | ||
45 | + <div class="tab-pane" id="registered"> | ||
46 | + <table id='lastNRegistered' class="table table-striped table-hover"> | ||
47 | + <thead> | ||
48 | + <tr><th>租约</th><th>时间戳</th></tr> | ||
49 | + </thead> | ||
50 | + <tbody> | ||
51 | + <#if lastNRegistered?has_content> | ||
52 | + <#list lastNRegistered as entry> | ||
53 | + <tr><td>${entry.date?datetime}</td><td>${entry.id}</td></tr> | ||
54 | + </#list> | ||
55 | + <#else> | ||
56 | + <tr><td colspan="2">没有可用的资源</td></tr> | ||
57 | + </#if> | ||
58 | + </tbody> | ||
59 | + </table> | ||
60 | + </div> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | + <script type="text/javascript" src="eureka/js/wro.js" ></script> | ||
65 | + <script type="text/javascript"> | ||
66 | + $(function () { | ||
67 | + $('#myTab a:last').tab('show') | ||
68 | + }) | ||
69 | + </script> | ||
70 | + </body> | ||
71 | +</html> |
@@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
1 | +<h1>系统状态</h1> | ||
2 | +<div class="row"> | ||
3 | + <div class="col-md-6"> | ||
4 | + <table id='instances' class="table table-condensed table-striped table-hover"> | ||
5 | + <#if amazonInfo??> | ||
6 | + <tr> | ||
7 | + <td>服务注册和发现</td> | ||
8 | + <td>AMI: ${amiId!}</td> | ||
9 | + </tr> | ||
10 | + <tr> | ||
11 | + <td>空间</td> | ||
12 | + <td>${availabilityZone!}</td> | ||
13 | + </tr> | ||
14 | + <tr> | ||
15 | + <td>示例Id</td> | ||
16 | + <td>${instanceId!}</td> | ||
17 | + </tr> | ||
18 | + </#if> | ||
19 | + <tr> | ||
20 | + <td>环境</td> | ||
21 | + <td>${environment!}</td> | ||
22 | + </tr> | ||
23 | + <tr> | ||
24 | + <td>数据中心</td> | ||
25 | + <td>${datacenter!}</td> | ||
26 | + </tr> | ||
27 | + </table> | ||
28 | + </div> | ||
29 | + <div class="col-md-6"> | ||
30 | + <table id='instances' class="table table-condensed table-striped table-hover"> | ||
31 | + <tr> | ||
32 | + <td>当前时间</td> | ||
33 | + <td>${currentTime}</td> | ||
34 | + </tr> | ||
35 | + <tr> | ||
36 | + <td>运行</td> | ||
37 | + <td>${upTime}</td> | ||
38 | + </tr> | ||
39 | + <tr> | ||
40 | + <td>启用租约到期时间</td> | ||
41 | + <td>${registry.leaseExpirationEnabled?c}</td> | ||
42 | + </tr> | ||
43 | + <tr> | ||
44 | + <td>续订阈值</td> | ||
45 | + <td>${registry.numOfRenewsPerMinThreshold}</td> | ||
46 | + </tr> | ||
47 | + <tr> | ||
48 | + <td>续订 (最后一分钟)</td> | ||
49 | + <td>${registry.numOfRenewsInLastMin}</td> | ||
50 | + </tr> | ||
51 | + </table> | ||
52 | + </div> | ||
53 | +</div> | ||
54 | + | ||
55 | +<#if isBelowRenewThresold> | ||
56 | + <#if !registry.selfPreservationModeEnabled> | ||
57 | + <h4 id="uptime"><font size="+1" color="red"><b>续订小于阈值。自保存模式已关闭。如果出现网络/其他问题, 这可能不会保护实例过期。</b></font></h4> | ||
58 | + <#else> | ||
59 | + <h4 id="uptime"><font size="+1" color="red"><b> 紧急!注册中心可能不正确地验证身份, 当他们没有的情况下。续订小于阈值, 因此实例不会过期, 只是为了安全起见。</b></font></h4> | ||
60 | + </#if> | ||
61 | +<#elseif !registry.selfPreservationModeEnabled> | ||
62 | + <h4 id="uptime"><font size="+1" color="red"><b>自保存模式已关闭。如果出现网络/其他问题, 这可能不会保护实例过期。</b></font></h4> | ||
63 | +</#if> | ||
64 | + | ||
65 | +<h1>服务副本</h1> | ||
66 | +<ul class="list-group"> | ||
67 | + <#list replicas as replica> | ||
68 | + <li class="list-group-item"><a href="${replica.value}">${replica.key}</a></li> | ||
69 | + </#list> | ||
70 | +</ul> | ||
71 | + |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<!doctype html> | ||
3 | +<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | ||
4 | +<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | ||
5 | +<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | ||
6 | +<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | ||
7 | + <head> | ||
8 | + <base href="<@spring.url basePath/>"> | ||
9 | + <meta charset="utf-8"> | ||
10 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
11 | + <title>服务注册和发现</title> | ||
12 | + <meta name="description" content=""> | ||
13 | + <meta name="viewport" content="width=device-width"> | ||
14 | + | ||
15 | + <link rel="stylesheet" href="eureka/css/wro.css"> | ||
16 | + | ||
17 | + </head> | ||
18 | + | ||
19 | + <body id="one"> | ||
20 | + <#include "header.ftl"> | ||
21 | + <div class="container-fluid xd-container"> | ||
22 | + <#include "navbar.ftl"> | ||
23 | + <h1>当前注册的服务实例</h1> | ||
24 | + <table id='instances' class="table table-striped table-hover"> | ||
25 | + <thead style="background-color: #328eba"> | ||
26 | + <tr><th>应用</th><th>申请</th><th>可用性区域</th><th>状态</th></tr> | ||
27 | + </thead> | ||
28 | + <tbody> | ||
29 | + <#if apps?has_content> | ||
30 | + <#list apps as app> | ||
31 | + <tr> | ||
32 | + <td><b>${app.name}</b></td> | ||
33 | + <td> | ||
34 | + <#list app.amiCounts as amiCount> | ||
35 | + <b>${amiCount.key}</b> (${amiCount.value})<#if amiCount_has_next>,</#if> | ||
36 | + </#list> | ||
37 | + </td> | ||
38 | + <td> | ||
39 | + <#list app.zoneCounts as zoneCount> | ||
40 | + <b>${zoneCount.key}</b> (${zoneCount.value})<#if zoneCount_has_next>,</#if> | ||
41 | + </#list> | ||
42 | + </td> | ||
43 | + <td> | ||
44 | + <#list app.instanceInfos as instanceInfo> | ||
45 | + <#if instanceInfo.isNotUp> | ||
46 | + <font color=red size=+1><b> | ||
47 | + </#if> | ||
48 | + <b>${instanceInfo.status}</b> (${instanceInfo.instances?size}) - | ||
49 | + <#if instanceInfo.isNotUp> | ||
50 | + </b></font> | ||
51 | + </#if> | ||
52 | + <#list instanceInfo.instances as instance> | ||
53 | + <#if instance.isHref> | ||
54 | + <a href="${instance.url}" target="_blank">${instance.id}</a> | ||
55 | + <#else> | ||
56 | + ${instance.id} | ||
57 | + </#if><#if instance_has_next>,</#if> | ||
58 | + </#list> | ||
59 | + </#list> | ||
60 | + </td> | ||
61 | + </tr> | ||
62 | + </#list> | ||
63 | + <#else> | ||
64 | + <tr><td colspan="4">没有可用的实例</td></tr> | ||
65 | + </#if> | ||
66 | + | ||
67 | + </tbody> | ||
68 | + </table> | ||
69 | + | ||
70 | + <h1>一般信息</h1> | ||
71 | + | ||
72 | + <table id='generalInfo' class="table table-striped table-hover"> | ||
73 | + <thead> | ||
74 | + <tr><th>名称</th><th>值</th></tr> | ||
75 | + </thead> | ||
76 | + <tbody> | ||
77 | + <#list statusInfo.generalStats?keys as stat> | ||
78 | + <tr> | ||
79 | + <td>${stat}</td><td>${statusInfo.generalStats[stat]!""}</td> | ||
80 | + </tr> | ||
81 | + </#list> | ||
82 | + <#list statusInfo.applicationStats?keys as stat> | ||
83 | + <tr> | ||
84 | + <td>${stat}</td><td>${statusInfo.applicationStats[stat]!""}</td> | ||
85 | + </tr> | ||
86 | + </#list> | ||
87 | + </tbody> | ||
88 | + </table> | ||
89 | + | ||
90 | + <h1>示例信息</h1> | ||
91 | + | ||
92 | + <table id='instanceInfo' class="table table-striped table-hover"> | ||
93 | + <thead> | ||
94 | + <tr><th>名称</th><th>值</th></tr> | ||
95 | + <thead> | ||
96 | + <tbody> | ||
97 | + <#list instanceInfo?keys as key> | ||
98 | + <tr> | ||
99 | + <td>${key}</td><td>${instanceInfo[key]!""}</td> | ||
100 | + </tr> | ||
101 | + </#list> | ||
102 | + </tbody> | ||
103 | + </table> | ||
104 | + </div> | ||
105 | + <script type="text/javascript" src="eureka/js/wro.js" ></script> | ||
106 | + <script type="text/javascript"> | ||
107 | + $(document).ready(function() { | ||
108 | + $('table.stripeable tr:odd').addClass('odd'); | ||
109 | + $('table.stripeable tr:even').addClass('even'); | ||
110 | + }); | ||
111 | + </script> | ||
112 | + </body> | ||
113 | +</html> |
cloud/server2/src/main/java/com/sincere/server2/listener/EurekaInstanceCanceledListener.java
0 → 100644
@@ -0,0 +1,59 @@ | @@ -0,0 +1,59 @@ | ||
1 | +package com.sincere.server2.listener; | ||
2 | + | ||
3 | + | ||
4 | +import com.netflix.discovery.shared.Applications; | ||
5 | +import com.netflix.eureka.EurekaServerContextHolder; | ||
6 | +import com.netflix.eureka.registry.PeerAwareInstanceRegistry; | ||
7 | +import lombok.extern.slf4j.Slf4j; | ||
8 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceCanceledEvent; | ||
9 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRegisteredEvent; | ||
10 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaInstanceRenewedEvent; | ||
11 | +import org.springframework.cloud.netflix.eureka.server.event.EurekaRegistryAvailableEvent; | ||
12 | +import org.springframework.context.ApplicationEvent; | ||
13 | +import org.springframework.context.ApplicationListener; | ||
14 | +import org.springframework.context.annotation.Configuration; | ||
15 | + | ||
16 | +/** | ||
17 | + * 用于监听eureka服务停机通知 | ||
18 | + * Created by ace on 2017/7/8. | ||
19 | + */ | ||
20 | +@Slf4j | ||
21 | +@Configuration | ||
22 | +public class EurekaInstanceCanceledListener implements ApplicationListener { | ||
23 | + @Override | ||
24 | + public void onApplicationEvent(ApplicationEvent applicationEvent) { | ||
25 | + // 服务挂掉事件 | ||
26 | + if (applicationEvent instanceof EurekaInstanceCanceledEvent) { | ||
27 | + EurekaInstanceCanceledEvent event = (EurekaInstanceCanceledEvent) applicationEvent; | ||
28 | + // 获取当前Eureka实例中的节点信息 | ||
29 | + PeerAwareInstanceRegistry registry = EurekaServerContextHolder.getInstance().getServerContext().getRegistry(); | ||
30 | + Applications applications = registry.getApplications(); | ||
31 | + // 遍历获取已注册节点中与当前失效节点ID一致的节点信息 | ||
32 | + applications.getRegisteredApplications().forEach((registeredApplication) -> { | ||
33 | + registeredApplication.getInstances().forEach((instance) -> { | ||
34 | + if (instance.getInstanceId().equals(event.getServerId())) { | ||
35 | + log.debug("服务:" + instance.getAppName() + " 挂啦。。。"); | ||
36 | + // // TODO: 2017/9/3 扩展消息提醒 邮件、手机短信、微信等 | ||
37 | + } | ||
38 | + }); | ||
39 | + }); | ||
40 | + | ||
41 | + | ||
42 | + } | ||
43 | + if (applicationEvent instanceof EurekaInstanceRegisteredEvent) { | ||
44 | + EurekaInstanceRegisteredEvent event = (EurekaInstanceRegisteredEvent) applicationEvent; | ||
45 | + log.debug("服务:" + event.getInstanceInfo().getAppName() + " 注册成功啦。。。"); | ||
46 | + } | ||
47 | + if (applicationEvent instanceof EurekaInstanceRenewedEvent) { | ||
48 | + EurekaInstanceRenewedEvent event = (EurekaInstanceRenewedEvent) applicationEvent; | ||
49 | + log.debug("心跳检测服务:" + event.getInstanceInfo().getAppName() + "。。"); | ||
50 | + } | ||
51 | + if (applicationEvent instanceof EurekaRegistryAvailableEvent) { | ||
52 | + log.debug("服务 Aualiable。。"); | ||
53 | + } | ||
54 | + | ||
55 | + } | ||
56 | + | ||
57 | + | ||
58 | +} | ||
59 | + |
cloud/server2/src/main/resources/application.yaml
@@ -9,22 +9,29 @@ spring: | @@ -9,22 +9,29 @@ spring: | ||
9 | 9 | ||
10 | eureka: | 10 | eureka: |
11 | instance: | 11 | instance: |
12 | - preferIpAddress: true | ||
13 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 | 12 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 |
14 | lease-renewal-interval-in-seconds: 10 | 13 | lease-renewal-interval-in-seconds: 10 |
15 | lease-expiration-duration-in-seconds: 60 | 14 | lease-expiration-duration-in-seconds: 60 |
16 | - | ||
17 | hostname: localhost | 15 | hostname: localhost |
16 | + prefer-ip-address: true | ||
18 | server: | 17 | server: |
19 | #是否开启保护模式 | 18 | #是否开启保护模式 |
20 | - enable-self-preservation: true | ||
21 | - eviction-interval-timer-in-ms: 4000 | 19 | + enable-self-preservation: false #关闭服务器自我保护,客户端心跳检测15分钟内错误达到80%服务会保护,导致别人还认为是好用的服务 |
20 | + eviction-interval-timer-in-ms: 4000 #清理间隔(单位毫秒,默认是60*1000)5秒将客户端剔除的服务在服务注册列表中剔除# | ||
22 | #当进入保护模式的情况下,注册中心不会注销服务,以兼容分区故障 | 21 | #当进入保护模式的情况下,注册中心不会注销服务,以兼容分区故障 |
23 | - renewal-percent-threshold: 0.5 | 22 | + renewal-percent-threshold: 0.5 # 指定每分钟需要收到的续约次数的阈值,默认值就是:0.85 |
23 | + response-cache-update-interval-ms: 3000 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上 #eureka server刷新readCacheMap的时间,注意,client读取的是readCacheMap,这个时间决定了多久会把readWriteCacheMap的缓存更新到readCacheMap上默认30s | ||
24 | + response-cache-auto-expiration-in-seconds: 180 #eureka server缓存readWriteCacheMap失效时间,这个只有在这个时间过去后缓存才会失效,失效前不会更新,过期后从registry重新读取注册服务信息,registry是一个ConcurrentHashMap。 | ||
24 | client: | 25 | client: |
25 | #是否注册eureka,高可用的清况下使用 | 26 | #是否注册eureka,高可用的清况下使用 |
26 | - register-with-eureka: true | 27 | + register-with-eureka: true #false:不作为一个客户端注册到注册中心,是否将自身的实例信息注册到eureka服务器 |
27 | #是否启用获取服务注册信息 | 28 | #是否启用获取服务注册信息 |
28 | - fetch-registry: true | 29 | + fetch-registry: false #为true时,可以启动,但报异常:Cannot execute request on any known server ,是否从eureka服务端获取注册信息,消费者需要配置true |
30 | + instance-info-replication-interval-seconds: 10 | ||
31 | + registry-fetch-interval-seconds: 30 #从eureka服务端获取注册信息的间隔时间 | ||
29 | service-url: | 32 | service-url: |
30 | - defaultZone: http://localhost:8761/eureka/ | ||
31 | \ No newline at end of file | 33 | \ No newline at end of file |
34 | + defaultZone: http://localhost:8761/eureka/ | ||
35 | + | ||
36 | + | ||
37 | +ribbon: | ||
38 | + ServerListRefreshInterval: 1000 #刷新服务列表源的间隔时间 | ||
32 | \ No newline at end of file | 39 | \ No newline at end of file |
@@ -0,0 +1,26 @@ | @@ -0,0 +1,26 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<nav class="navbar navbar-default" role="navigation" > | ||
3 | + <div class="container"> | ||
4 | + <div class="navbar-header"> | ||
5 | + <a class="navbar-brand" href="<@spring.url dashboardPath/>"><span></span></a> | ||
6 | + <button type="button" class="navbar-toggle" data-toggle="collapse" data-target="#bs-example-navbar-collapse-1"> | ||
7 | + <span class="sr-only">切换导航</span> | ||
8 | + <span class="icon-bar"></span> | ||
9 | + <span class="icon-bar"></span> | ||
10 | + <span class="icon-bar"></span> | ||
11 | + </button> | ||
12 | + </div> | ||
13 | + <div class="collapse navbar-collapse" id="bs-example-navbar-collapse-1"> | ||
14 | + <ul class="nav navbar-nav navbar-right"> | ||
15 | + <li> | ||
16 | + <a href="<@spring.url dashboardPath/>">主页</a> | ||
17 | + </li> | ||
18 | + <li> | ||
19 | + <a href="<@spring.url dashboardPath/>/lastn">最近启动的1000个服务</a> | ||
20 | + </li> | ||
21 | + </ul> | ||
22 | + </div> | ||
23 | + </div> | ||
24 | +</nav> | ||
25 | + | ||
26 | + |
@@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<!doctype html> | ||
3 | +<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | ||
4 | +<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | ||
5 | +<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | ||
6 | +<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | ||
7 | + <head> | ||
8 | + <base href="<@spring.url basePath/>"> | ||
9 | + <title>注册中心-事件</title> | ||
10 | + <link rel="stylesheet" type="text/css" href="eureka/css/wro.css"> | ||
11 | + </head> | ||
12 | + <body id="three"> | ||
13 | + | ||
14 | + <!--[if lt IE 7]> | ||
15 | + <p>您使用的是旧版本的浏览器。请升级您的浏览器以改善您的体验。</p> | ||
16 | + <![endif]--> | ||
17 | + | ||
18 | + <#include "header.ftl"> | ||
19 | + | ||
20 | + <div class="container-fluid xd-container"> | ||
21 | + <#include "navbar.ftl"> | ||
22 | + | ||
23 | + <div id="xd-jobs" class="tab-pane active col-md-12"> | ||
24 | + <ul class="nav nav-tabs" role="tablist" id="myTab"> | ||
25 | + <li class="active"><a data-toggle="tab" href="#cancelled">最后1000个取消的租约</a></li> | ||
26 | + <li><a data-toggle="tab" href="#registered">最近1000份新注册租约</a></li> | ||
27 | + </ul> | ||
28 | + <div class="tab-content"> | ||
29 | + <div class="tab-pane" id="cancelled"> | ||
30 | + <table id='lastNCanceled' class="table table-striped table-hover"> | ||
31 | + <thead> | ||
32 | + <tr><th>租约</th><th>时间戳</th></tr> | ||
33 | + </thead> | ||
34 | + <tbody> | ||
35 | + <#if lastNCanceled?has_content> | ||
36 | + <#list lastNCanceled as entry> | ||
37 | + <tr><td>${entry.date?datetime}</td><td>${entry.id}</td></tr> | ||
38 | + </#list> | ||
39 | + <#else> | ||
40 | + <tr><td colspan="2">没有可用的资源</td></tr> | ||
41 | + </#if> | ||
42 | + <tbody> | ||
43 | + </table> | ||
44 | + </div> | ||
45 | + <div class="tab-pane" id="registered"> | ||
46 | + <table id='lastNRegistered' class="table table-striped table-hover"> | ||
47 | + <thead> | ||
48 | + <tr><th>租约</th><th>时间戳</th></tr> | ||
49 | + </thead> | ||
50 | + <tbody> | ||
51 | + <#if lastNRegistered?has_content> | ||
52 | + <#list lastNRegistered as entry> | ||
53 | + <tr><td>${entry.date?datetime}</td><td>${entry.id}</td></tr> | ||
54 | + </#list> | ||
55 | + <#else> | ||
56 | + <tr><td colspan="2">没有可用的资源</td></tr> | ||
57 | + </#if> | ||
58 | + </tbody> | ||
59 | + </table> | ||
60 | + </div> | ||
61 | + </div> | ||
62 | + </div> | ||
63 | + </div> | ||
64 | + <script type="text/javascript" src="eureka/js/wro.js" ></script> | ||
65 | + <script type="text/javascript"> | ||
66 | + $(function () { | ||
67 | + $('#myTab a:last').tab('show') | ||
68 | + }) | ||
69 | + </script> | ||
70 | + </body> | ||
71 | +</html> |
@@ -0,0 +1,71 @@ | @@ -0,0 +1,71 @@ | ||
1 | +<h1>系统状态</h1> | ||
2 | +<div class="row"> | ||
3 | + <div class="col-md-6"> | ||
4 | + <table id='instances' class="table table-condensed table-striped table-hover"> | ||
5 | + <#if amazonInfo??> | ||
6 | + <tr> | ||
7 | + <td>服务注册和发现</td> | ||
8 | + <td>AMI: ${amiId!}</td> | ||
9 | + </tr> | ||
10 | + <tr> | ||
11 | + <td>空间</td> | ||
12 | + <td>${availabilityZone!}</td> | ||
13 | + </tr> | ||
14 | + <tr> | ||
15 | + <td>示例Id</td> | ||
16 | + <td>${instanceId!}</td> | ||
17 | + </tr> | ||
18 | + </#if> | ||
19 | + <tr> | ||
20 | + <td>环境</td> | ||
21 | + <td>${environment!}</td> | ||
22 | + </tr> | ||
23 | + <tr> | ||
24 | + <td>数据中心</td> | ||
25 | + <td>${datacenter!}</td> | ||
26 | + </tr> | ||
27 | + </table> | ||
28 | + </div> | ||
29 | + <div class="col-md-6"> | ||
30 | + <table id='instances' class="table table-condensed table-striped table-hover"> | ||
31 | + <tr> | ||
32 | + <td>当前时间</td> | ||
33 | + <td>${currentTime}</td> | ||
34 | + </tr> | ||
35 | + <tr> | ||
36 | + <td>运行</td> | ||
37 | + <td>${upTime}</td> | ||
38 | + </tr> | ||
39 | + <tr> | ||
40 | + <td>启用租约到期时间</td> | ||
41 | + <td>${registry.leaseExpirationEnabled?c}</td> | ||
42 | + </tr> | ||
43 | + <tr> | ||
44 | + <td>续订阈值</td> | ||
45 | + <td>${registry.numOfRenewsPerMinThreshold}</td> | ||
46 | + </tr> | ||
47 | + <tr> | ||
48 | + <td>续订 (最后一分钟)</td> | ||
49 | + <td>${registry.numOfRenewsInLastMin}</td> | ||
50 | + </tr> | ||
51 | + </table> | ||
52 | + </div> | ||
53 | +</div> | ||
54 | + | ||
55 | +<#if isBelowRenewThresold> | ||
56 | + <#if !registry.selfPreservationModeEnabled> | ||
57 | + <h4 id="uptime"><font size="+1" color="red"><b>续订小于阈值。自保存模式已关闭。如果出现网络/其他问题, 这可能不会保护实例过期。</b></font></h4> | ||
58 | + <#else> | ||
59 | + <h4 id="uptime"><font size="+1" color="red"><b> 紧急!注册中心可能不正确地验证身份, 当他们没有的情况下。续订小于阈值, 因此实例不会过期, 只是为了安全起见。</b></font></h4> | ||
60 | + </#if> | ||
61 | +<#elseif !registry.selfPreservationModeEnabled> | ||
62 | + <h4 id="uptime"><font size="+1" color="red"><b>自保存模式已关闭。如果出现网络/其他问题, 这可能不会保护实例过期。</b></font></h4> | ||
63 | +</#if> | ||
64 | + | ||
65 | +<h1>服务副本</h1> | ||
66 | +<ul class="list-group"> | ||
67 | + <#list replicas as replica> | ||
68 | + <li class="list-group-item"><a href="${replica.value}">${replica.key}</a></li> | ||
69 | + </#list> | ||
70 | +</ul> | ||
71 | + |
@@ -0,0 +1,113 @@ | @@ -0,0 +1,113 @@ | ||
1 | +<#import "/spring.ftl" as spring /> | ||
2 | +<!doctype html> | ||
3 | +<!--[if lt IE 7]> <html class="no-js lt-ie9 lt-ie8 lt-ie7"> <![endif]--> | ||
4 | +<!--[if IE 7]> <html class="no-js lt-ie9 lt-ie8"> <![endif]--> | ||
5 | +<!--[if IE 8]> <html class="no-js lt-ie9"> <![endif]--> | ||
6 | +<!--[if gt IE 8]><!--> <html class="no-js"> <!--<![endif]--> | ||
7 | + <head> | ||
8 | + <base href="<@spring.url basePath/>"> | ||
9 | + <meta charset="utf-8"> | ||
10 | + <meta http-equiv="X-UA-Compatible" content="IE=edge"> | ||
11 | + <title>服务注册和发现</title> | ||
12 | + <meta name="description" content=""> | ||
13 | + <meta name="viewport" content="width=device-width"> | ||
14 | + | ||
15 | + <link rel="stylesheet" href="eureka/css/wro.css"> | ||
16 | + | ||
17 | + </head> | ||
18 | + | ||
19 | + <body id="one"> | ||
20 | + <#include "header.ftl"> | ||
21 | + <div class="container-fluid xd-container"> | ||
22 | + <#include "navbar.ftl"> | ||
23 | + <h1>当前注册的服务实例</h1> | ||
24 | + <table id='instances' class="table table-striped table-hover"> | ||
25 | + <thead style="background-color: #328eba"> | ||
26 | + <tr><th>应用</th><th>申请</th><th>可用性区域</th><th>状态</th></tr> | ||
27 | + </thead> | ||
28 | + <tbody> | ||
29 | + <#if apps?has_content> | ||
30 | + <#list apps as app> | ||
31 | + <tr> | ||
32 | + <td><b>${app.name}</b></td> | ||
33 | + <td> | ||
34 | + <#list app.amiCounts as amiCount> | ||
35 | + <b>${amiCount.key}</b> (${amiCount.value})<#if amiCount_has_next>,</#if> | ||
36 | + </#list> | ||
37 | + </td> | ||
38 | + <td> | ||
39 | + <#list app.zoneCounts as zoneCount> | ||
40 | + <b>${zoneCount.key}</b> (${zoneCount.value})<#if zoneCount_has_next>,</#if> | ||
41 | + </#list> | ||
42 | + </td> | ||
43 | + <td> | ||
44 | + <#list app.instanceInfos as instanceInfo> | ||
45 | + <#if instanceInfo.isNotUp> | ||
46 | + <font color=red size=+1><b> | ||
47 | + </#if> | ||
48 | + <b>${instanceInfo.status}</b> (${instanceInfo.instances?size}) - | ||
49 | + <#if instanceInfo.isNotUp> | ||
50 | + </b></font> | ||
51 | + </#if> | ||
52 | + <#list instanceInfo.instances as instance> | ||
53 | + <#if instance.isHref> | ||
54 | + <a href="${instance.url}" target="_blank">${instance.id}</a> | ||
55 | + <#else> | ||
56 | + ${instance.id} | ||
57 | + </#if><#if instance_has_next>,</#if> | ||
58 | + </#list> | ||
59 | + </#list> | ||
60 | + </td> | ||
61 | + </tr> | ||
62 | + </#list> | ||
63 | + <#else> | ||
64 | + <tr><td colspan="4">没有可用的实例</td></tr> | ||
65 | + </#if> | ||
66 | + | ||
67 | + </tbody> | ||
68 | + </table> | ||
69 | + | ||
70 | + <h1>一般信息</h1> | ||
71 | + | ||
72 | + <table id='generalInfo' class="table table-striped table-hover"> | ||
73 | + <thead> | ||
74 | + <tr><th>名称</th><th>值</th></tr> | ||
75 | + </thead> | ||
76 | + <tbody> | ||
77 | + <#list statusInfo.generalStats?keys as stat> | ||
78 | + <tr> | ||
79 | + <td>${stat}</td><td>${statusInfo.generalStats[stat]!""}</td> | ||
80 | + </tr> | ||
81 | + </#list> | ||
82 | + <#list statusInfo.applicationStats?keys as stat> | ||
83 | + <tr> | ||
84 | + <td>${stat}</td><td>${statusInfo.applicationStats[stat]!""}</td> | ||
85 | + </tr> | ||
86 | + </#list> | ||
87 | + </tbody> | ||
88 | + </table> | ||
89 | + | ||
90 | + <h1>示例信息</h1> | ||
91 | + | ||
92 | + <table id='instanceInfo' class="table table-striped table-hover"> | ||
93 | + <thead> | ||
94 | + <tr><th>名称</th><th>值</th></tr> | ||
95 | + <thead> | ||
96 | + <tbody> | ||
97 | + <#list instanceInfo?keys as key> | ||
98 | + <tr> | ||
99 | + <td>${key}</td><td>${instanceInfo[key]!""}</td> | ||
100 | + </tr> | ||
101 | + </#list> | ||
102 | + </tbody> | ||
103 | + </table> | ||
104 | + </div> | ||
105 | + <script type="text/javascript" src="eureka/js/wro.js" ></script> | ||
106 | + <script type="text/javascript"> | ||
107 | + $(document).ready(function() { | ||
108 | + $('table.stripeable tr:odd').addClass('odd'); | ||
109 | + $('table.stripeable tr:even').addClass('even'); | ||
110 | + }); | ||
111 | + </script> | ||
112 | + </body> | ||
113 | +</html> |
cloud/zkAttendance/src/main/java/com/sincere/att/AttApplication.java
@@ -15,6 +15,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients; | @@ -15,6 +15,9 @@ import org.springframework.cloud.openfeign.EnableFeignClients; | ||
15 | @SpringBootApplication | 15 | @SpringBootApplication |
16 | public class AttApplication { | 16 | public class AttApplication { |
17 | 17 | ||
18 | +// public static void main(String[] args) { | ||
19 | +// SpringApplication.run(AttApplication.class, args); | ||
20 | +// } | ||
18 | public static void main(String[] args) { | 21 | public static void main(String[] args) { |
19 | SpringApplication.run(AttApplication.class, args); | 22 | SpringApplication.run(AttApplication.class, args); |
20 | } | 23 | } |