How does systemd-resolved prioritize DNS servers in Ubuntu?
It can get complicated and it depends.
Systems resolvd allows per link DNS servers and provides an API for applications and daemons like for example VPN clients to dynamically register DNS servers and/or search domains when the VPN gets activated.
resolvectl status should give you an idea of the current effective systemd-resolved configuration though.
The most simple scenario is to only have one or more name servers in the classic /etc/resolv.conf similar to what you seem to have have in your net plan.
That is the same as having only DNS= entries and no FallbackDNS= the resolved.conf configuration file. Those name servers will get queried in parallel.
What algorithm does systemd-resolved use to choose which DNS server to query first?
The applicable DNS servers all get queried in parallel.
Does order matter?
No. That was how the classic glibc resolver would work (each query there would always use the first name server in /etc/resolv.conf and only when it encountered an error from that first nameserver would the next ones be tried in order) but systemd queries all equivalent DNS servers in parallel, and although there is the FallbackDNS= setting that is not quite the same behavior.
If DNS resolution succeeds but the HTTP request fails (403, etc.), will systemd-resolved retry with a different DNS server?
No. For Systemd-resolved and DNS resolution there is no failure.
In a custom application you can do whatever makes sense for you but for the typical web client there was a host found, a web request was made and the server returned a clear response. Unfortunately an error code response but that is not a DNS resolution failure or something that a resolver needs to fix.
Can I enforce strict priority ordering so servers are tried in exact specified order?
Not as far as I know (and order shouldn’t matter, each equivalent DNS server should get you a result)
AFAIK You would need to not use systemd-resolved and let the classic glibc resolver do its thing. That did query (max 3) nameservers in the order they are defined in /etc/resolv.conf where always the first one gets used. (Unless tuned with for example options rotate) Only when that first doesn't doesn’t respond at all or responds with certain errors will the second nameserver be used as fallback or the third when both previous ones fail.
After failover to a secondary DNS server, will it try the primary again automatically? Or requires netplan apply?
What failover?
What secondary?
All configured DNS servers get queried in parallel.
When they all fail the FallbackDNS= servers get queried for that failed query. AFAIK When a subsequent query is made it again first goes to the DNS= servers and in case all of those still don’t respond the fallback happens for that query too.
Can systemd-resolved rotate through all configured DNS servers for load balancing?
Not that I know. It uses all of them in parallel rather than one after the other.
Load balancing is normally not done by a client anyway but rather by the provider of the service.