往往一个系统会涉及到多个项目组成,在微服务时代使用springboot+springcloud,每个项目都只有自己独立的功能模块,相互协作完成系统的功能。使用docker容器部署java项目时,每个项目都是一个独立的容器部署,有自己内部容器的文件、资源等。最近一段时间遇到过一个坑,就是在一个容器项目中生成了一个资源文件,然后在另外一个容器中读取该文件出现以下错误
文件路径:/tmp/455255854584682114758956.ico,异常消息:/tmp/455255854584682114758956.ico (No such file or directory)
具体先看下被调用者代码:
@RestController
@RequestMapping("/fileUpload")
public class FileUploadController {
Logger logger= LoggerFactory.getLogger(FileUploadController.class);
@PostMapping(value = "/upload")
@ApiOperation(value = "上传文件", notes = "上传文件")
public ResponseEntity<?> upload(@RequestBody FileDto dto) {
FileInputStream fis = null ;
try{
fis = new FileInputStream(dto.getAbsolutePath());
}catch (Exception e ){
logger.error("文件路径:{},异常消息:{}",dto.getAbsolutePath(),e.getMessage());
throw new RuntimeException("文件不存在");
}
// 文件读取完后业务处理
FileManagerDto fileDto = new FileManagerDto();
BeanUtil.beanCopy(dto,fileDto, CommonAttribute.FRAMEWORK_FIELDS,false);
return ResponseEntity.ok(fileDto);
}
}
被调用者服务配置:
spring:
profiles:
active: dev
application:
name: file-upload
调用者代码:
public void createFile(FileDto dto) {
String absolutePath = "";
File file = null;
file = File.createTempFile("logo", dto.getFileName);
if(file != null ){
absolutePath = file.getAbsolutePath();
}
HttpHeaders httpHeaders = new HttpHeaders();
httpHeaders.setContentType(MediaType.APPLICATION_JSON);
Map bodyMap = new HashMap();
// 设置文件路径
bodyMap.put("absolutePath",absolutePath);
String json = JSONObject.toJSON(bodyMap).toString();
HttpEntity<String> requestParam = new HttpEntity<String>(json, httpHeaders);
String reqUrl = "http://file-upload/fileUpload/upload";
//通过restTemplate调用
String result = restTemplate.postForEntity( reqUrl, requestParam, String.class).getBody();
System.out.println(result);
}
调用者服务配置
spring:
application:
name: file-management
profiles:
active: dev
这里两个服务均是注册在nacos中,所以调用的时候可以根据被调用者的服务名进行调用
格式:http://服务名/controller的RequestMapping/方法的PostMapping。
在本地开发时由于两个服务不是采用容器部署,他们共享的是同一个目录,在服务器上采用容器部署的时候,两个项目有独立的文件存储和目录,file-management服务创建了文件,但是在file-upload服务中读取不到文件抛出异常:
/tmp/455255854584682114758956.ico (No such file or directory)
这里解决办法有两个
1 :保证文件生成和文件读取在同一个容器中,于是把文件生成的代码逻辑移动到file-upload中
2 :让容器能够有公共的访问目录,容器提供了一个可以将目录挂载到宿主机的方法,这样容器就可以共享数据信息
具体docker容器目录挂载方法参阅docker官方文档