- problems_microservice
- 1 seata報錯1
- 2 seata報錯2
- 3 seata報錯4
- 4 seata報錯5
- 5 seata報錯6
- 6 springboot啟動報錯Service id not legal hostname
- 7 springboot啟動報錯
- 8 seata事務不生效
- 9 gateway的過濾器(繼承GlobalFilter)中使用openFeign報錯
- 10 skywalking的gateway插件版本不對不兼容
- 11 springboot微服務啟動報錯,無法連接到nacos
- 12 springboot啟動時無法加載skywalking插件
- 13 springboot啟動報錯 No Feign Client for loadBalancing defined
- 14
- 15
- 16
problems_microservice
1 seata報錯1
2021-12-02 13:33:31.529 INFO --- io.seata.spring.annotation.datasource.SeataAutoDataSourceProxyCreator.getAdvicesAndAdvisorsForBean[45]: Auto proxy of [dataSource]
Property 'mapperLocations' was not specified.
2021-12-02 13:33:33.857 ERROR --- io.seata.core.rpc.netty.NettyClientChannelManager.reconnect[164]: Failed to get available servers: endpoint format should like ip:port
java.lang.IllegalArgumentException: endpoint format should like ip:port
RCA: (不對,這個RCA是錯誤的!)
yaml文件中,沒有配置driver-class-name,url,username,password。這些是配置seata數據庫的數據源。
solution:配置如下:
spring:
# 數據源配置
datasource:
driver-class-name: com.mysql.cj.jdbc.Driver
url: jdbc:mysql://ip:port/seata?useUnicode=true&characterEncoding=utf8&zeroDateTimeBehavior=convertToNull&useSSL=false&serverTimezone=GMT%2B8
username: user1
password: password1
后續:隨着對seata的熟悉,發現這里並非配置seata數據庫,而是業務數據庫,只不過,把配置項直接放到datasource:
下面了(以前在 datasource:
下,還有一個 druid:
)
而seata的數據庫的數據源配置,是在nacos的 store.db.url
等配置項中。
2 seata報錯2
io.seata.common.exception.FrameworkException: can not register RM,err:can not connect to services-server.
RCA:啟動seata-server時,未手動設置端口。
solution:
-
服務端和客戶端配置服務名稱相同。
-
seata客戶端配置file.conf:
如果registry.conf中設置其配置類型為nacos,則不會使用file.conf中的配置,而是使用nacos中的配置。
從而這里不用修改file.conf文件,而是要到nacos的seata_env命名空間中,修改 vgroupMapping.orders_tx_group 的值。
service {
# vgroupMapping.orders_tx_group = "seata-server"
vgroupMapping.orders_tx_group = "default"
}
- 啟動seata-server時,手動設置端口,命令為:nohup ./bin/seata-server.sh -p 8091 -h 127.0.0.1 -m db >log.out 2>1 &
3 seata報錯4
### Error updating database. Cause: java.sql.SQLException: java.sql.SQLSyntaxErrorException: Table 'db1.undo_log' doesn't exist
RCA: 在我的數據庫db1中沒有建立undo_log表。
solution:
建表,語句如下:
CREATE TABLE `undo_log` (
`branch_id` bigint(20) NOT NULL COMMENT 'branch transaction id',
`xid` varchar(128) NOT NULL COMMENT 'global transaction id',
`context` varchar(128) NOT NULL COMMENT 'undo_log context,such as serialization',
`rollback_info` longblob NOT NULL COMMENT 'rollback info',
`log_status` int(11) NOT NULL COMMENT '0:normal status,1:defense status',
`log_created` datetime(6) NOT NULL COMMENT 'create datetime',
`log_modified` datetime(6) NOT NULL COMMENT 'modify datetime',
UNIQUE KEY `ux_undo_log` (`xid`,`branch_id`)
) ENGINE=InnoDB COMMENT='AT transaction mode undo table';
4 seata報錯5
2021-12-02 16:36:31.539 ERROR --- [ main] com.alibaba.druid.pool.DruidDataSource : init datasource error, url: jdbc:mysql://192.168.1.10:3306/seata?useUnicode=true&rewriteBatchedStatements=true
==> com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure
RCA: nacos上配置的store.db.url 錯誤,
solution:
錯誤的配置值:jdbc:mysql://錯誤IP:錯誤端口/seata?useUnicode=true&rewriteBatchedStatements=true
改為正確的配置值:jdbc:mysql://新IP:新端口/seata?useUnicode=true&rewriteBatchedStatements=true
5 seata報錯6
處理分布式事務時,openfeign調用遠端接口,遠端接口報錯:
Caused by: java.sql.SQLException: java.lang.RuntimeException: com.fasterxml.jackson.databind.exc.InvalidDefinitionException: Type id handling not implemented for type java.lang.Object (by serializer of type com.fasterxml.jackson.databind.ser.impl.UnsupportedTypeSerializer) (through reference chain: io.seata.rm.datasource.undo.BranchUndoLog["sqlUndoLogs"]->java.util.ArrayList[0]->io.seata.rm.datasource.undo.SQLUndoLog["beforeImage"]->io.seata.rm.datasource.sql.struct.TableRecords["rows"]->java.util.ArrayList[0]->io.seata.rm.datasource.sql.struct.Row["fields"]->java.util.ArrayList[2]->io.seata.rm.datasource.sql.struct.Field["value"])
RCA:seata默認使用jackson反序列化,但是有bug,官方還未修復。
SOLUTION1:將序列化器改為kryo。
修改方法:
在springboot的yaml配置文件中增加配置:
seata: client: undo: logSerialization: kryo
在pom.xml中引入kryo的3個依賴。
SOLUTION2:將序列化器改為fastjson。
修改方法:
在springboot的yaml配置文件中增加配置:
seata: client: undo: logSerialization: fastjson
seata: client: undo: log-serialization: fastjson # 這里可以使用屬性logSerialization,也可以使用屬性 log-serialization
在pom.xml中引入fastjson的1個依賴。
6 springboot啟動報錯Service id not legal hostname
ERRORLOG:
java.lang.IllegalStateException: Service id not legal hostname (inventorys_just_for_test)
RCA: Feign的服務名不能使用下划線,需使用中橫線,如:“aa-bb”。
SOLUTION: 將服務名的下划線改為中橫線。
7 springboot啟動報錯
ERRORLOG:
2021-12-07 10:21:12-[TID: N/A]- ERROR --- com.alibaba.nacos.client.config.http.ServerHttpAgent : [NACOS ConnectException httpPost] currentServerAddr: http://localhost:8848, err : 拒絕連接 (Connection refused)
java.net.ConnectException: [NACOS HTTP-POST] The maximum number of tolerable server reconnection errors has been reached
RCA: 可能是系統沒有發現bootstrap.yml配置文件,或者bootstrap.yml中配置的nacos上的配置文件沒有被識別到,或沒有被拉取到本地。
SOLUTION: 后來自己好了,好像也沒做啥操作。
8 seata事務不生效
猜測1:和seata在nacos上注冊的ip是 172.18.0.1(我的虛擬網卡的IP) 有關,seata-server可能要配置為該IP。 猜測錯誤。
猜測2:可能和這個配置項 seata.enable-auto-data-source-proxy: false 有關。確實是的,這個配置改為true后,就生效了。
但是又報第二個錯誤,並且一直在重復報該錯誤,如下:
2021-12-12 17:34:57-[TID: N/A]- INFO --- io.seata.rm.AbstractRMHandler : Branch Rollbacked result: PhaseTwo_RollbackFailed_Retryable
2021-12-12 17:34:58-[TID: N/A]- INFO --- io.seata.core.rpc.processor.client.RmBranchRollbackProcessor : rm handle branch rollback process:xid=172.18.0.1:8091:213348906720825344,branchId=213348911154204673,branchType=AT,resourceId=jdbc:mysql://localhost:3306/java_inventories,applicationData=null
2021-12-12 17:34:58-[TID: N/A]- INFO --- io.seata.rm.AbstractRMHandler : Branch Rollbacking: 172.18.0.1:8091:213348906720825344 213348911154204673 jdbc:mysql://localhost:3306/java_inventories
2021-12-12 17:34:58-[TID: N/A]- INFO --- io.seata.rm.datasource.DataSourceManager : branchRollback failed. branchType:[AT], xid:[172.18.0.1:8091:213348906720825344], branchId:[213348911154204673], resourceId:[jdbc:mysql://localhost:3306/java_inventories], applicationData:[null]. reason:[Branch session rollback failed and try again later xid = 172.18.0.1:8091:213348906720825344 branchId = 213348911154204673 Timestamp format must be yyyy-mm-dd hh:mm:ss[.fffffffff]]
原因是它一直在重試回滾事務,但每次都回滾失敗,所以重復報錯。
回滾失敗的原因是,無法處理時間類型的序列化/返序列化。說時間格式不對,以下的undo_log中的數據中,時間格式是 2021-11-30T14:11:11,不符合它說的 yyyy-mm-dd hh:mm:ss[.fffffffff]]:
{"branchId":213340637168144385,"sqlUndoLogs":[{"afterImage":{"rows":[{"fields":[{"keyType":"PRIMARY_KEY","name":"id","type":12,"value":"1465564039652311041"},{"keyType":"NULL","name":"product_id","type":12,"value":"10012"},{"keyType":"NULL","name":"product_name","type":12,"value":"鍵盤"},{"keyType":"NULL","name":"stock_count","type":12,"value":"982"},{"keyType":"NULL","name":"delete_flag","type":4,"value":0},{"keyType":"NULL","name":"create_time","type":93,"value":"2021-11-30T14:11:11"},{"keyType":"NULL","name":"update_time","type":93,"value":"2021-12-12T16:32:07"}]}],"tableName":"biz_stock"},"beforeImage":{"rows":[{"fields":[{"keyType":"PRIMARY_KEY","name":"id","type":12,"value":"1465564039652311041"},{"keyType":"NULL","name":"product_id","type":12,"value":"10012"},{"keyType":"NULL","name":"product_name","type":12,"value":"鍵盤"},{"keyType":"NULL","name":"stock_count","type":12,"value":"984"},{"keyType":"NULL","name":"delete_flag","type":4,"value":0},{"keyType":"NULL","name":"create_time","type":93,"value":"2021-11-30T14:11:11"},{"keyType":"NULL","name":"update_time","type":93,"value":"2021-12-12T16:32:07"}]}],"tableName":"biz_stock"},"sqlType":"UPDATE","tableName":"biz_stock"}],"xid":"172.18.0.1:8091:213340630356594688"}
有2個解決方法:1 時間類型改為使用時間戳,不用datetime;2 由fastjson改為使用kryo序列化方式(jackson序列化器更加坑,不能用)。
9 gateway的過濾器(繼承GlobalFilter)中使用openFeign報錯
// 代碼中注入了feignClient
@Autowired
private AuthenticateClient authenticateClient;
ERROR1:
Description:
Parameter 2 of constructor in com.example.ciic.gateway.filter.PreUaaFilter required a bean of type 'com.example.ciic.gateway.service.AuthenticateClient' that could not be found.
Action:
Consider defining a bean of type 'com.example.ciic.gateway.service.AuthenticateClient' in your configuration.
ACTION:
走了很多彎路,比如使用 ApplicationContext 獲取feignClient對象,比如改用 WebClient 。
RCA1:
未在gateway的main類上添加注解 @EnableFeignClients,導致feignClient沒有注入
SOLUTION1:增加如下注解 @EnableFeignClients:
@EnableFeignClients(defaultConfiguration = FeignConfig.class)
@SpringBootApplication
@Slf4j
public class GatewayApplication {
public static void main(String[] args) {
SpringApplication.run(GatewayApplication.class, args);
}
}
NOTE:下次尋找解決方法前,可以先檢查一遍使用feign的各項配置是否都做了,以免浪費時間。
ERROR2:
[reactor-http-epoll-3] com.example.ciic.gateway.filter.PreUaaFilter No qualifying bean of type 'org.springframework.boot.autoconfigure.http.HttpMessageConverters' available: expected at least 1 bean which qualifies as autowire candidate. Dependency annotations: {@org.springframework.beans.factory.annotation.Autowired(required=true)}
SOLUTION2:
添加配置類注入 HttpMessageConverterConfig 的 bean(實際代碼中我使用了 FeignConfig.java這個類名稱,因為以后可能會配置feign的其他配置項):
package com.example.ciic.gateway.config;
import org.springframework.beans.factory.ObjectProvider;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.boot.autoconfigure.http.HttpMessageConverters;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.converter.HttpMessageConverter;
import java.util.stream.Collectors;
@Configuration
public class HttpMessageConverterConfig {
@Bean
@ConditionalOnMissingBean
public HttpMessageConverters messageConverters(ObjectProvider<HttpMessageConverter<?>> converters) {
return new HttpMessageConverters(converters.orderedStream().collect(Collectors.toList()));
}
}
ERROR3:
com.netflix.client.ClientException: Load balancer does not have available server for client: ciicsh-java-authenticate
ACTION3:
no action. 是nacos的問題,或者是網絡問題。
ERROR4:
[302] during [POST] to [http://ciicsh-java-authenticate/authenticate/verifyToken] [AuthenticateClient#verifyToken(String)]: []
或者報這個錯:cannot retry due to redirection, in streaming mode executing POST http://localhost:9010/authenticate/refreshToken
RCA4:
當未登錄認證系統時,該請求 /authenticate/verifyToken
被重定向到登錄頁了:http://10.17.9.213:9010/login
上述報錯信息中,302代表臨時重定向。
SOLUTION4:
在認證系統的ShiroConfig.java中添加不攔截url的規則:
public ShiroFilterFactoryBean shiroFilterFactoryBean(SecurityManager securityManager) {
...
filterChainDefinitionMap.put("/authenticate/**", "anon,captchaValidate");
...
}
ERROR5:
feign.codec.DecodeException: Could not extract response: no suitable HttpMessageConverter found for response type [interface io.jsonwebtoken.Claims] and content type [application/json]
RCA5:
測試過程中,我把 FeignConfig.java 刪除了。
SOLUTION5:
和 SOLUTION2 一樣。
ERROR6:
UnknownContentTypeException: Could not extract response: no suitable HttpMessageConverter found for response type [interface io.jsonwebtoken.Claims] and content type [application/json]
RCA6:
我看了下,feign返回的對象轉換為了LinkedHashMap。而不是我期望的 Claims 對象。
SOLUTION6:
把 feignClient 接口中的方法的返回值改為 HashMap<String, Object>
:
@FeignClient(value = "ciicsh-java-authenticate", path = "/authenticate")
public interface AuthenticateClient {
@PostMapping("/verifyToken")
HashMap<String, Object> verifyToken(Map<String, String> map);
@PostMapping("/refreshToken")
HashMap<String, Object> refreshToken(Map<String, String> map);
}
10 skywalking的gateway插件版本不對不兼容
SOLUTION:
# 查看gateway的版本
ll skywalking/agent/plugins/apm-spring-cloud-gateway*
# result: -rw-rw-r-- 1 witt witt 43569 12月 9 17:12 skywalking/agent/plugins/apm-spring-cloud-gateway-2.1.x-plugin-8.5.0.jar
# 刪除gateway2.1.x
rm -f skywalking/agent/plugins/apm-spring-cloud-gateway-2.1.x-plugin-8.5.0.jar
# 替換為gateway2.0.x
cp skywalking/agent/optional-plugins/apm-spring-cloud-gateway-2.0.x-plugin-8.5.0.jar skywalking/agent/plugins/
11 springboot微服務啟動報錯,無法連接到nacos
ERROR:
ERROR [com.alibaba.nacos.client.config.security.updater] com.alibaba.nacos.client.security.SecurityProxy [SecurityProxy] login http request failed url: http://nacos.k8sdev.ciicsh.com:80/nacos/v1/auth/users/login, params: {username=java}, bodyMap: {password=java}, errorMsg: errCode: 100, errMsg: Nacos serialize for class [com.alibaba.nacos.common.http.HttpRestResult] failed.
com.alibaba.nacos.client.config.impl.ClientWorker [fixed-nacos.k8sdev.ciicsh.com_80-java_demo] [sub-server-error] no right, dataId=gateway, group=DEFAULT_GROUP, tenant=java_demo
There was an unexpected error (type=Forbidden, status=403).unknown user!
一開始查網上資料,以為是nacos的需要配置用戶名密碼,還有context-path,yml文件中配置如下,然並卵:
spring:
cloud:
nacos:
config:
name: gateway
namespace: ******
# 此處必須要加端口號,否則會使用默認端口號8848
server-addr: nacos-dev.com:8848
file-extension: yaml
username: java
password: java
context-path: /nacos # 可不設置,默認就是這個值
RCA:是server-addr配置錯誤了,nacos-dev需要修改為nacos-test。修改為如下配置:
server-addr: nacos-test.com:8848
12 springboot啟動時無法加載skywalking插件
RCA:skywalking相關的啟動參數配置到了 Program arguments中,如下圖所示:
應該配置在 VM options中,如下圖所示:
13 springboot啟動報錯 No Feign Client for loadBalancing defined
ERROR:
Caused by: java.lang.IllegalStateException: No Feign Client for loadBalancing defined. Did you forget to include spring-cloud-starter-netflix-ribbon or spring-cloud-starter-loadbalancer?
RCA:
我的openfeign和loadbalancer的版本都為3.0.4.
feign需要其他的依賴提供負載均衡功能,為此需要ribbon或者 loadbalancer,但是這個版本中,經過測試,必須去掉ribbon,添加loadbalancer
SOLUTION:
pom.xml中的配置如下:
<!-- 服務調用 openFeign -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-openfeign</artifactId>
<exclusions>
<exclusion>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-netflix-ribbon</artifactId>
</exclusion>
</exclusions>
</dependency>
<!-- openFeign 依賴 loadbalancer 的負載均衡功能 -->
<dependency>
<groupId>org.springframework.cloud</groupId>
<artifactId>spring-cloud-starter-loadbalancer</artifactId>
</dependency>