需求:公司产品一直是nodejs的后台,采用的eggjs框架,也不是最新版本,现有有需求需求将这些应用集成到微服务的注册中心,领导要求用java。
思路:用spring cloud gateway将需要暴露的接口url转发,并将这个gateway注册到注册中心
方案:
1、转发原有nodejs的后台服务
用Springboot建立一个gateway项目,引入gateway
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-gateway</artifactId>
<version>3.1.2</version>
</dependency>
配置文件
server:
port: 9984 #此模块的PORT
servlet:
encoding:
force: true
charset: UTF-8
enabled: true
tomcat:
uri-encoding: UTF-8
spring:
application:
name: gateway
cloud:
nacos:
discovery:
server-addr: localhost:8848 #注册到nacos
service=test-provider: gateway
gateway:
discovery:
locator:
enabled: true #开启从注册中心动态创建路由的功能,利用微服务名进行路由
routes:
- id: gateway1 #路由的ID,没有固定规则但要求唯一,建议配合服务名
uri: http://IP:PORT #匹配nodejs的服务IP及端口号
predicates:
- Path=/你的需要暴露的服务的根路径/** # 断言,路径相匹配的进行路由
app文件
@SpringBootApplication
@EnableDiscoveryClient // cloud 需要 注册中心==发现
public class App {
public static void main(String[] args) {
SpringApplication.run(App.class, args);
}
}
启动后在nacos中,可以看到此项,这时可以测试9984端口已经转发了原有nodejs的服务
2、消费者
需要引入loadblancer否则报错
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
<version>3.1.1</version>
</dependency>
(1)RestTemplate进行服务请求
新建一个MyConfiguration类对RestTemplate进行配置
package org.example;
import org.springframework.cloud.client.loadbalancer.LoadBalanced;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.client.RestTemplate;
@Configuration
public class MyConfiguration {
@LoadBalanced
@Bean
public RestTemplate restTemplate(){
return new RestTemplate();
}
}
在使用的类进行初始化
private final RestTemplate restTemplate;
@Autowired
public ConsumerController(RestTemplate restTemplate) {
this.restTemplate = restTemplate;
}
使用
String url = "http://nacos中模块名称/...";
HttpHeaders headers = new HttpHeaders();
headers.setContentType(MediaType.APPLICATION_JSON);
HttpEntity<String> request = new HttpEntity<>(pars.toJSONString(), headers);
//请求
String result = restTemplate.postForObject(url, request, String.class);
//System.out.println(result);
这种模式可以很好的调用springboot 自己发布的URL,但是不知道为什么请求对nodejs的服务返回的为乱码,所有的都乱码不只是中文乱码。
分析认为是GZIP的原因,nodejs的服务打开了GZIP,所以这里需要处理。可以用以下进行GZIP处理,完美结局
ResponseEntity<byte[]> responseEntity = restTemplate.postForEntity(url, request, byte[].class);
GZIPInputStream fi = new GZIPInputStream(new ByteArrayInputStream(responseEntity.getBody()));
BufferedReader reader = new BufferedReader(new InputStreamReader(fi));
StringWriter writer = new StringWriter();
String line = "";
while ((line = reader.readLine()) != null) {
writer.write(line);
}
result = writer.toString();
(2)FeignClient,此种方法更加优雅
引用
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<version>3.1.1</version>
</dependency>
接口
package org.example;
import com.alibaba.fastjson.JSONObject;
import org.springframework.cloud.openfeign.FeignClient;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
/**
* @author
* * @date 2024/12/8
*/
@FeignClient("gateway")//这里写nacos中服务名称
public interface ProviderFeignClient {
//这里是post请求,json格式参数的例子
@PostMapping("/.....")//这里写具体的路径
String tblcodefactoryv6_GetList(@RequestBody JSONObject pars);
}
使用时就很简单了
//初始化
@Autowired
ProviderFeignClient providerFeignClient;
//方法中这样用就好了,简洁
result = providerFeignClient.tblcodefactoryv6_GetList(pars);
以上就是使用gateway将nodejs的服务加入到nacos注册中心作为微服务的过程。