正文
什么是Docker Compose
在微服务盛行的今天,我们通常是这么定义Compose的:对容器的统一启动和关闭的编排工具。
但是我以前还是有个疑惑,谁会用Compose在一台服务器上部署多个服务呢?干脆直接用单体服务就行了!直到我遇到了以下的一个需求,让我明白了在一台服务器上不得不用多个服务的时候,Compose可以通过sidecar的模式,让服务很简单的通过127.0.0.1调用另一个服务
需求遇到不合适的语言
一个用golang开发的某个项目,希望根据学生信息打印学籍,学籍表其中一部分如下
go中并不是没有操作word的库,但是操作这样一个复杂的word,并且填好信息还是有很大难度。所以我们想到了一个实现方案。
实现方案
1.通过excel定义一个一样的模板
2.golang往excel的指定cell里填值
这样相对往word里填值就简单很多,其中一部分代码
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 | xlsx.SetCellValue( "Sheet1" , "C3" , student.Major.Name) xlsx.SetCellValue( "Sheet1" , "F3" , student.ClassInfo.Name) xlsx.SetCellValue( "Sheet1" , "J3" , student.SchoolSystem) xlsx.SetCellValue( "Sheet1" , "B4" , student.Name) xlsx.SetCellValue( "Sheet1" , "D4" , student.BeforName) xlsx.SetCellValue( "Sheet1" , "F4" , student.Gender) xlsx.SetCellValue( "Sheet1" , "H4" , student.Nation) xlsx.SetCellValue( "Sheet1" , "B5" , student.IdCardNo) xlsx.SetCellValue( "Sheet1" , "F5" , student.HomePlace) xlsx.SetCellValue( "Sheet1" , "B6" , student.Birthday.Format( "20060102" )) xlsx.SetCellValue( "Sheet1" , "D6" , student.EntranceTime.Format( "20060102" )) xlsx.SetCellValue( "Sheet1" , "F6" , student.JoinTeamTime) xlsx.SetCellValue( "Sheet1" , "B7" , student.FamilyAddress) xlsx.SetCellValue( "Sheet1" , "F7" , student.HealthStatus) |
3.把excel转成pdf返给前端,供其展示或者打印
我在github了没找到golang把excel转成pdf的库(有推荐可以留言),于是想到了.net里的FreeSpire.Xls库可以很方便实现excel转pdf的功能,所以需要有个.net api把go生产并填好的excel转成pdf,于是我新建了一个.net webapi,项目名定义成pdfprocessor,其中定一个Controller
[Route("[controller]")] public class PDFController : ControllerBase { private readonly ILogger<PDFController> _logger; public PDFController(ILogger<PDFController> logger) { _logger = logger; } [HttpPost] public async Task<IActionResult> HttpPostAsync() { try { Stream stream = Request.Body; byte[] buffer = new byte[Request.ContentLength.Value]; stream.Position = 0L; stream.ReadAsync(buffer, 0, buffer.Length); Workbook wb = new Workbook(); wb.LoadFromStream(stream); Worksheet ws = wb.Worksheets[0]; var streamReturn = new MemoryStream(); ws.SaveToPdfStream(streamReturn); return File(streamReturn, "application/octet-stream"); } catch (Exception ex) { _logger.LogError("", ex); return BadRequest(ex.Message); } } }
4.部署go项目与.net项目
因为这是一个很小的单体项目,那么如何使这个部署与调用相对简单就是我需要考虑的问题了,这时候我想到了Docker Compose。
我可以通过docker-compose同时启动go api和.net api,最重要的还是可以让go与.net项目使用同一个network的方式,使go api通过127.0.0.1:port来调用.net api,拓扑如下
5.go api通过127.0.0.1调用 .net api
这样.net api就成了go api的一个sidecar,为其服务
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | response, err := http.Post( "http://127.0.0.1:6081/PDF" , "multipart/form-data;boundary=" +multipart.NewWriter(bytes.NewBufferString( "" )).Boundary(), bytes.NewReader(byteA)) if err != nil { c.Bad(err.Error()) return } defer response.Body.Close() if response.StatusCode != 200 { data, _ := ioutil.ReadAll(response.Body) c.Bad(string(data)) return } pdfFilePth := fmt.Sprintf( "./templates/tmp/%s.pdf" , uuid.New()) f, err := os.Create(pdfFilePth) if err != nil { c.Bad(err.Error()) return } io.Copy(f, response.Body) c.Ctx.Output.Download(pdfFilePth, "data.xlsx" ) |
6.docker-compose部署
编写go的dockerfile
1 2 3 4 5 6 7 8 9 10 11 | FROM library/golang WORKDIR /app RUN go env -w GO111MODULE=on RUN go env -w GOPROXY=https: //goproxy.cn,direct ADD api/ /app RUN cd /app RUN go mod tidy RUN go build main. go ENTRYPOINT [ "/app/main" ] EXPOSE 6080 |
编写.net的dockerfile
#See https://aka.ms/containerfastmode to understand how Visual Studio uses this Dockerfile to build your images for faster debugging. FROM mcr.microsoft.com/dotnet/aspnet:6.0 AS base RUN apt-get update RUN apt-get install -y --no-install-recommends libgdiplus libc6-dev RUN apt-get install -y fontconfig xfonts-utils COPY /pdfprocessor/fonts/ /usr/share/fonts/ RUN mkfontscale RUN mkfontdir RUN fc-cache -fv WORKDIR /app EXPOSE 6081 FROM mcr.microsoft.com/dotnet/sdk:6.0 AS build WORKDIR /src COPY ["pdfprocessor/pdfprocessor.csproj", "pdfprocessor/"] RUN dotnet restore "pdfprocessor/pdfprocessor.csproj" COPY . . WORKDIR "/src/pdfprocessor" RUN dotnet build "pdfprocessor.csproj" -c Release -o /app/build FROM build AS publish RUN dotnet publish "pdfprocessor.csproj" -c Release -o /app/publish FROM base AS final WORKDIR /app COPY --from=publish /app/publish . ENTRYPOINT ["dotnet", "pdfprocessor.dll"]
编写docker-compose.yaml,让goapi与.net api使用同一个network
version: '3.4' services: pdfprocessor: image: pdfprocessor build: context: . dockerfile: pdfprocessor/Dockerfile depends_on: - eduadmin network_mode: "service:eduadmin" eduadmin: image: eduadmin build: context: . dockerfile: api/Dockerfile ports: - "6080:6080" - "6088:6088"
7.通过docker-compose up -d启动服务
查看pdf展示效果
最后想说docker-compose真香!

【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· AI与.NET技术实操系列(二):开始使用ML.NET
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?