Azure App Service中运行内嵌WireMock的SpringBoot应用解决方案咨询
解决Azure App Service中SpringBoot内嵌WireMock的端口冲突问题
问题核心原因
Azure App Service仅对外暴露80/443端口,这两个端口已被平台反向代理占用,用于将外部请求转发到你的SpringBoot应用内部端口(你配置的8085),所以直接让WireMock绑定80/443会触发“Address already in use”错误。以下是三种可行的解决思路:
方案1:通过SpringBoot请求转发代理WireMock请求
在SpringBoot中添加一个代理控制器,将特定路径的请求转发到内部运行的WireMock服务(8082端口),外部仅需通过SpringBoot的端口(映射到Azure的80/443)访问即可。
示例代码:
import org.springframework.http.HttpEntity; import org.springframework.http.HttpHeaders; import org.springframework.http.HttpMethod; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.RequestBody; import org.springframework.web.bind.annotation.RequestMapping; import org.springframework.web.bind.annotation.RestController; import org.springframework.web.client.RestTemplate; import javax.servlet.http.HttpServletRequest; @RestController @RequestMapping("/wiremock") public class WireMockProxyController { private final RestTemplate restTemplate = new RestTemplate(); private static final String WIREMOCK_INTERNAL_URL = "http://localhost:8082"; @RequestMapping(value = "/**", method = {HttpMethod.GET, HttpMethod.POST, HttpMethod.PUT, HttpMethod.DELETE}) public ResponseEntity<?> proxyToWireMock(HttpServletRequest request, @RequestBody(required = false) String requestBody) { // 截取WireMock的目标路径 String targetPath = request.getRequestURI().replaceFirst("/wiremock", ""); String targetUrl = WIREMOCK_INTERNAL_URL + targetPath; // 复制原请求头 HttpHeaders headers = new HttpHeaders(); request.getHeaderNames().forEach(header -> headers.add(header, request.getHeader(header))); HttpEntity<String> requestEntity = new HttpEntity<>(requestBody, headers); return restTemplate.exchange(targetUrl, request.getMethod(), requestEntity, String.class); } }
部署后,外部通过https://<你的应用服务名>.azurewebsites.net/wiremock/[WireMock接口路径]即可访问WireMock桩服务。
方案2:将WireMock集成到SpringBoot的Web容器中
让WireMock作为Servlet挂载到SpringBoot的Tomcat/Jetty容器,共用同一个端口,无需单独启动WireMock的服务器。
步骤1:添加依赖(Maven示例)
<dependency> <groupId>com.github.tomakehurst</groupId> <artifactId>wiremock-jre8</artifactId> <version>2.35.0</version> <!-- 若生产环境需启用,将scope改为compile --> <scope>test</scope> </dependency>
步骤2:注册WireMock Servlet
import com.github.tomakehurst.wiremock.WireMockServer; import com.github.tomakehurst.wiremock.core.WireMockConfiguration; import org.springframework.boot.web.servlet.ServletRegistrationBean; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; @Configuration public class WireMockIntegrationConfig { @Bean public ServletRegistrationBean<WireMockServlet> wireMockServletRegistration() { // 配置WireMock不单独占用端口 WireMockConfiguration config = WireMockConfiguration.options().port(-1); WireMockServer wireMockServer = new WireMockServer(config); wireMockServer.start(); // 将WireMock Servlet挂载到/wiremock路径下 return new ServletRegistrationBean<>(wireMockServer.getServlet(), "/wiremock/*"); } }
此方案下,WireMock和SpringBoot完全共用同一个端口,外部访问规则同方案1,且避免了端口冲突问题。
方案3:使用Azure App Service虚拟应用程序(适合独立WireMock服务)
如果你的WireMock是独立服务而非内嵌,可在Azure App Service中配置虚拟应用程序,将WireMock部署到子路径(如/wiremock),平台会自动将该路径的请求转发到对应的应用。但由于你是内嵌在SpringBoot中,前两个方案更直接高效。
内容的提问来源于stack exchange,提问作者Shilpa
相关产品推荐
相关产品推荐

