springcloud微服务之间怎么通信,springcloud相互调用

  springcloud微服务之间怎么通信,springcloud相互调用

  00-1010 1.解决方案1,解决方案22,代码实现3,结果展示4,总结

  00-1010因为近期项目需要国际化,之前的国际语言切换放在微服务之前独立的SpringBoot服务中。

  目前由于业务需要和不同模块可复用的要求,已经拆分为以下服务:zuul网关服务、**dx服务(含主服务)、**ai(部分推荐ai服务)、message(消息咨询服务)、forum(论坛服务)等。

  如果只是按照之前的方式切换**dx服务的语言;其他微服务不知道当前请求的请求是什么语言系统。

  意思是**dx服务是en语言,但其他服务是zh(中文)。

  因为这个问题,我在开始项目国际改版的时候就知道了这个问题。我就知道有这个问题。起初,有些人不相信;终于遇到问题,信了!当你遇到问题时,你必须使用相关的解决方案来解决它。

  于是本人就是想到了有如下两种解决方案:

  00-1010在网关服务中编写统一的交换语言接口(Zuul);使用切换语言时调用其他服务的切换语言接口。这是最容易实现的方法。

  如下图所示:

  这种方法比较原始直接,但是有很多文字代码。当你想和每个微服务交流的时候,你得提供一个接口,为网关(Zuul)修改语言系统。

  00-1010:网关(Zuul)服务层切换语言时,获取切换语言的参数;使用LocaleContextHolder临时存储当前切换语言的信息;

  然后在Zuul的过滤器中获取当前请求的参数后,从LocaleContextHolder中获取之前语言切换的参数值。然后把这个参数传递给其他微服务;其他微服务可以通过请求获取最新的切换语言参数;然后切换后成功获取最新的语言信息。

  如下图所示:

  方案一与方案二比较后,我选择第二个选项。

  

目录

@Override公共对象run(){ request context CTX=request context . getcurrent context();http servlet request request=CTX . get request();string reqUrl=request . getrequesturl()。toString();http session session=request . getsession();MapString,Object user=(MapString,Object)session . get attribute( user );如果(!(requrl . contains( permission user/userLogin ) (requrl . contains( no auth ) requrl . contains( app API )){ String[]act profile=env . getactiveprofiles();string cur profile=act profile[0];if(string utils . starts with(cur profile, dev ){//dev环境不过滤返回null}//判断用户ID是否存在,如果不存在,跳转到登录界面如果(!CheckIslogin (CTX,用户)){//system.out.println (session缺失: request.getSession()。getId());返回null}//释放URL if(checkisignoreurl(request)){ addusertotozuulrequestheader(user)在ignoreUrls中配置;返回null}//检查url是否可以访问if(!checkIsUrlHasRight(ctx)) {

 

  return null; } //从会话之中获得当前登录用户的userId,判断用户是否被踢 if (checkUserIsKickout(ctx, user)) { return null; } } //可以往后走了,把session放入request的header中 addUserToZuulRequestHeader(user); //语言包 setLanguageLocal(request); return null; } /** * 设置本地语言包 * */private void setLanguageLocal(HttpServletRequest request) {String lang = "zh";if (StringUtils.isNotEmpty(request.getParameter("lang"))) {lang = request.getParameter("lang");}else {lang=localeMessageSourceService.getCurrentLanguage();}switch(lang) {case "zh":LocaleContextHolder.setLocale(Locale.CHINESE);break;case "en":LocaleContextHolder.setLocale(Locale.ENGLISH);break;case "fr":LocaleContextHolder.setLocale(Locale.FRENCH); break;}//此处为获得请求的参数 然后在请求的参数里面加入暂存的语言携带参数 langRequestContext ctx = RequestContext.getCurrentContext();request.getParameterMap();Map<String,List<String>> requestQueryParams=ctx.getRequestQueryParams();if(requestQueryParams==null) {requestQueryParams=new HashMap<>();}//String langCode=request.getParameter("lang").toString();//讲需要新增的参数添加进去,被调用的微服务可以直接获取,就像普通的一样;框架会直接注入进去 ArrayList<String> arrayList = new ArrayList<>(); arrayList.add(lang); requestQueryParams.put("lang", arrayList); ctx.setRequestQueryParams(requestQueryParams);FrameWorkConstant.MSG_INFO_EMPTY = localeMessageSourceService.getMessage("msg.info.empty");FrameWorkConstant.MSG_INFO_SUCCESS = localeMessageSourceService.getMessage("msg.success.operate");FrameWorkConstant.MSG_INFO_FAILED= localeMessageSourceService.getMessage("msg.error.unknown");}ChangeLanauageConfigurer

  

import java.util.Locale; import org.springframework.context.annotation.Bean;import org.springframework.context.annotation.Configuration;import org.springframework.web.servlet.config.annotation.InterceptorRegistry;import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;import org.springframework.web.servlet.i18n.LocaleChangeInterceptor;import org.springframework.web.servlet.i18n.SessionLocaleResolver; /*** *@purpose:国际化启动配置类 *@since:2018年4月9日 ***/@Configurationpublic class ChangeLanauageConfigurer extends WebMvcConfigurerAdapter { /** * 描述 : 国际化配置类(会话区域解析器) * */@Bean public SessionLocaleResolver localeResolver() { SessionLocaleResolver slr = new SessionLocaleResolver();// System.out.println("aaaaaaaaaaaaaaaaaaaaaa");// // 设置默认语言 slr.setDefaultLocale(Locale.CHINESE); return slr; } @Bean public LocaleChangeInterceptor localeChangeInterceptor() { LocaleChangeInterceptor lci = new LocaleChangeInterceptor(); // 设置参数名 lci.setParamName("lang"); return lci; } public void addInterceptors(InterceptorRegistry registry) { registry.addInterceptor(localeChangeInterceptor()); }}

LocaleMessageSourceService

 

  

/*** *@purpose:本地化语言信息工具类 *@since:2018年3月30日 ***/@Servicepublic class LocaleMessageSourceService {@Autowiredprivate MessageSource messageSource; /** * *@param code:对应messages配置的key. *@return */ public String getMessage(String code){ //这里使用比较方便的方法,不依赖request. Locale locale = LocaleContextHolder.getLocale(); String lang = locale.getLanguage(); if(LanguageConstant.LANGUAGE_FR.equals(lang)) { locale = new Locale(lang,"FR"); } if(LanguageConstant.LANGUAGE_ZH.equals(lang)) { locale = new Locale(lang,"CN"); } if(LanguageConstant.LANGUAGE_EN.equals(lang)) { locale = new Locale(lang,"US"); } String message = messageSource.getMessage(code,null,locale); return message; } /** * 获得当前语言 * @param code * @return */ public String getCurrentLanguage(){ Locale locale = LocaleContextHolder.getLocale(); String lang = locale.getLanguage(); if(StringUtils.isEmpty(lang)) { lang = LanguageConstant.LANGUAGE_EN; } return lang; } }

 

  

3、成果展现

 

  在网关服务之中切换语言(en)后获得信息

  

 

  ai服务的语言体系

  

 

  **dx服务的语言体系

  

 

  网关切换为中文(zh)后其他服务语言返回

  

 

  ai服务语言切换结果

  

 

  **dx服务语言切换结果

  

 

  

 

  

4、总结

如果使用简单粗暴的方法,直接通过网关调用其他微服务;虽然能够实现功能;但是此方法比较笨重;同时书写的代码比较多。为后期维护带来很大的不便利。

 

  如果使用方案二在网关层进行统一处理,借助语言切换的能够在网关(Zuul)服务进行暂存和传递;同时动态添加切换语言后的参数到Request之中;能够便捷的把语言参数带到其他微服务之中。此方法值得推崇。

  以上为个人经验,希望能给大家一个参考,也希望大家多多支持盛行IT。

郑重声明:本文由网友发布,不代表盛行IT的观点,版权归原作者所有,仅为传播更多信息之目的,如有侵权请联系,我们将第一时间修改或删除,多谢。

留言与评论(共有 条评论)
   
验证码: