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 | -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 | 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 | 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 | 56 | * post请求传输json参数 | ... | ... |
... | ... | @@ -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 | 49 | \ No newline at end of file | ... | ... |
cloud/fIle-center/src/main/java/com/sincere/file/FileApplication.java
0 → 100644
... | ... | @@ -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 @@ |
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 @@ |
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 | 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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 | 182 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 | 42 | \ No newline at end of file | ... | ... |
cloud/geteway/src/main/resources/application.yml
... | ... | @@ -10,6 +10,7 @@ eureka: |
10 | 10 | lease-expiration-duration-in-seconds: 90 |
11 | 11 | lease-renewal-interval-in-seconds: 10 |
12 | 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 | 15 | spring: |
15 | 16 | cloud: |
... | ... | @@ -21,3 +22,9 @@ spring: |
21 | 22 | - Path=/haikangserver/** |
22 | 23 | filters: |
23 | 24 | - StripPrefix=1 |
25 | + - id: file-center | |
26 | + uri: lb://file-center | |
27 | + predicates: | |
28 | + - Path=/file-center/** | |
29 | + filters: | |
30 | + - StripPrefix=1 | |
24 | 31 | \ No newline at end of file | ... | ... |
cloud/geteway/src/test/java/com/example/geteway/GetewayApplicationTests.java
... | ... | @@ -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 | 1 | package com.sincere.haikangface.control; |
2 | 2 | |
3 | -import com.netflix.ribbon.proxy.annotation.Http; | |
4 | 3 | import com.sincere.common.dto.smartCampus.SZ_AttendanceDto; |
5 | -import com.sincere.common.util.BaiduApiUtiols; | |
4 | +import com.sincere.haikangface.utils.BaiduApiUtiols; | |
6 | 5 | import com.sincere.haikangface.CMSServer; |
7 | 6 | import com.sincere.haikangface.async.SendUserAsync; |
8 | 7 | import com.sincere.haikangface.bean.StudentBean; |
... | ... | @@ -23,10 +22,8 @@ import org.springframework.web.bind.annotation.RequestMethod; |
23 | 22 | import org.springframework.web.bind.annotation.RequestParam; |
24 | 23 | import org.springframework.web.bind.annotation.RestController; |
25 | 24 | import org.springframework.web.multipart.MultipartFile; |
26 | -import sun.rmi.runtime.Log; | |
27 | 25 | |
28 | 26 | import java.io.*; |
29 | -import java.math.BigInteger; | |
30 | 27 | import java.text.SimpleDateFormat; |
31 | 28 | import java.util.Calendar; |
32 | 29 | import java.util.Date; | ... | ... |
cloud/haikangface/src/main/java/com/sincere/haikangface/utils/BaiduApiUtiols.java
0 → 100644
... | ... | @@ -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 | 41 | <!-- <module>weigeng</module>--> |
42 | 42 | <!-- <module>independence</module>--> |
43 | 43 | <!-- <module>quartz</module>--> |
44 | - <!-- <module>zkAttendance</module>--> | |
44 | + <module>zkAttendance</module> | |
45 | + <module>fIle-center</module> | |
45 | 46 | </modules> |
46 | 47 | |
47 | 48 | <dependencies> |
... | ... | @@ -90,7 +91,12 @@ |
90 | 91 | <artifactId>commons-io</artifactId> |
91 | 92 | <version>2.6</version> |
92 | 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 | 100 | </dependencies> |
95 | 101 | |
96 | 102 | <dependencyManagement> |
... | ... | @@ -118,4 +124,23 @@ |
118 | 124 | </dependency> |
119 | 125 | </dependencies> |
120 | 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 | 146 | </project> | ... | ... |
cloud/server1/src/main/java/com/sincere/server1/listener/EurekaInstanceCanceledListener.java
0 → 100644
... | ... | @@ -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 | 9 | |
10 | 10 | eureka: |
11 | 11 | instance: |
12 | - preferIpAddress: true | |
13 | 12 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 |
14 | 13 | lease-renewal-interval-in-seconds: 10 |
15 | 14 | lease-expiration-duration-in-seconds: 60 |
16 | - | |
17 | 15 | hostname: localhost |
16 | + prefer-ip-address: true | |
18 | 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 | 25 | client: |
25 | 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 | 32 | service-url: |
30 | - defaultZone: http://localhost:8762/eureka/ | |
31 | 33 | \ No newline at end of file |
34 | + defaultZone: http://localhost:8762/eureka/ | |
35 | + | |
36 | +ribbon: | |
37 | + ServerListRefreshInterval: 1000 #刷新服务列表源的间隔时间 | ... | ... |
... | ... | @@ -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 @@ |
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 @@ |
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 @@ |
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 @@ |
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 | 9 | |
10 | 10 | eureka: |
11 | 11 | instance: |
12 | - preferIpAddress: true | |
13 | 12 | # 注册周期心跳 默认30s 这里改成5s 建议生成环境使用默认值30 |
14 | 13 | lease-renewal-interval-in-seconds: 10 |
15 | 14 | lease-expiration-duration-in-seconds: 60 |
16 | - | |
17 | 15 | hostname: localhost |
16 | + prefer-ip-address: true | |
18 | 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 | 25 | client: |
25 | 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 | 32 | service-url: |
30 | - defaultZone: http://localhost:8761/eureka/ | |
31 | 33 | \ No newline at end of file |
34 | + defaultZone: http://localhost:8761/eureka/ | |
35 | + | |
36 | + | |
37 | +ribbon: | |
38 | + ServerListRefreshInterval: 1000 #刷新服务列表源的间隔时间 | |
32 | 39 | \ No newline at end of file | ... | ... |
... | ... | @@ -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 @@ |
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 @@ |
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 @@ |
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 | 15 | @SpringBootApplication |
16 | 16 | public class AttApplication { |
17 | 17 | |
18 | +// public static void main(String[] args) { | |
19 | +// SpringApplication.run(AttApplication.class, args); | |
20 | +// } | |
18 | 21 | public static void main(String[] args) { |
19 | 22 | SpringApplication.run(AttApplication.class, args); |
20 | 23 | } | ... | ... |